【问题标题】:React Navigation: passing parameters to a route: TyperErrorReact Navigation:将参数传递给路由:TyperError
【发布时间】:2020-03-31 20:05:26
【问题描述】:

我的屏幕“NerdList”上有一个使用 ListItems (react-native-element) 和 Flatlist 构建的配置文件列表。当您单击列表中的配置文件时,应用程序应导航到“配置文件”屏幕并传​​递一个测试参数。 书呆子列表屏幕:

import React from "react";
import { withNavigation } from '@react-navigation/compat';
import { StyleSheet, FlatList} from "react-native";
import { ListItem } from "react-native-elements";
import nerdProfiles from '../constants/nerdProfiles';
import { Block, Text } from 'galio-framework';
import argonTheme from "../constants/Theme";
import { TouchableOpacity } from "react-native-gesture-handler";

class NerdList extends React.Component {
    renderItem = ({item}) => (
    <TouchableOpacity
    onPress={() => this.props.navigation.navigate('Profile', {test: 'Hello'})}
    >
      <ListItem 
        title={
          <Block>
          <Text style={styles.names}>
          {item.name}
          </Text>
        </Block>
        }
        subtitle={
          <Block>
            <Text style={styles.descriptions}>
            {item.shortDescription}
            </Text>
          </Block>
        }
        leftAvatar={{ source: { uri: item.image } }}
        bottomDivider
        chevron
            />
    </TouchableOpacity>
    );

    render() {
    return (
      <FlatList 
        data={nerdProfiles.bios}
        renderItem={this.renderItem}
        keyExtractor={item => item.id}
      />
    );
  };
};
export default withNavigation(NerdList);

单独导航可以工作,但是当我尝试传递参数时,我收到 TypeError: undefined is not an object (evalating '_ref3.route')。

这是我用来在“个人资料”屏幕上接收路线的代码:

const {test} = route.params;

完整的配置文件屏幕代码:

import React from "react";
import {
  StyleSheet,
  Dimensions,
  ScrollView,
  Image,
  ImageBackground,
  Platform
} from "react-native";
import { Block, Text, theme } from "galio-framework";

import { Button } from "../components";
import { Images, argonTheme } from "../constants";
import { HeaderHeight } from "../constants/utils";
import { FlatList, TouchableWithoutFeedback } from "react-native-gesture-handler";
import nerdProfiles from "../constants/nerdProfiles";
import ArticleCard from "../components/ArticleCard";
import VideoCard from "../components/VideoCard";


const { width, height } = Dimensions.get("screen");

const thumbMeasure = (width - 48 - 32) / 3;

//keyExtractor = (item, index) => index.toString()

class Profile extends React.Component {
  renderVideoItem = ({item}) => {
    return(
      <Block style={{ marginRight: theme.SIZES.BASE }}>
        <TouchableWithoutFeedback>
        <VideoCard
          item={item}
          imageStyle={{ width: "auto", height: 94 }}
          style={{ width: width / 3.75}}
        />
        </TouchableWithoutFeedback>
      </Block>
    );
  };

  renderArticleItem = ({item}) => {
    return(
      <Block style={{ marginRight: theme.SIZES.BASE }}>
        <TouchableWithoutFeedback>
        <ArticleCard
          item={item}
          imageStyle={{ width: "auto", height: 94 }}
          style={{ width: width / 3.75}}
        />
        </TouchableWithoutFeedback>
      </Block>
    );
  };

  render() {
    const { params } = this.props.navigation.state;
    const test= params ? params.test: null;
    return (
      <Block flex style={styles.profile}>
        <Block flex>
          <ImageBackground
            source={Images.ProfileBackground}
            style={styles.profileContainer}
            imageStyle={styles.profileBackground}
          >
            <ScrollView
              showsVerticalScrollIndicator={false}
              style={{ width, marginTop: "25%" }}
            >
              <Block flex style={styles.profileCard}>
                <Block middle style={styles.avatarContainer}>
                  <Image
                    source={{uri: nerdProfiles.bios[0].image}}
                    style={styles.avatar}
                  />
                </Block>
                <Block style={styles.info}>
                  <Block
                    middle
                    row
                    space="evenly"
                    style={{ marginTop: 20, paddingBottom: 24 }}
                  >
                    <Button
                      small
                      style={{ backgroundColor: argonTheme.COLORS.DEFAULT }}
                    >
                      FOLLOW
                    </Button>
                  </Block>
                  <Block row space="between">
                    <Block middle>
                      <Text
                        size={18}
                        color="#525F7F"
                        style={{ marginBottom: 4, fontFamily: 'open-sans-bold' }}
                      >
                        2K
                      </Text>
                      <Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.TEXT}>Followers</Text>
                    </Block>
                    <Block middle>
                      <Text
                        color="#525F7F"
                        size={18}
                        style={{ marginBottom: 4, fontFamily: 'open-sans-bold' }}
                      >
                        10
                      </Text>
                      {test}
                      <Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.TEXT}>Content</Text>
                    </Block>
                  </Block>
                </Block>
                <Block flex>
                  <Block middle style={styles.nameInfo}>
                    <Text style={{ fontFamily: 'open-sans-regular' }} size={28} color="#32325D">
                      {test}
                    </Text>
                    <Text size={16} color="#32325D" style={{ marginTop: 10, fontFamily: 'open-sans-light' }}>
                      {nerdProfiles.bios[0].location}
                    </Text>
                  </Block>
                  <Block style={styles.categories}>
                    <Button small>Math</Button>
                    <Button small>Finance</Button>
                    <Button small>Physics</Button>
                  </Block>
                  <Block middle style={{ marginTop: 30, marginBottom: 16 }}>
                    <Block style={styles.divider} />
                  </Block>
                  <Block middle>
                    <Text
                      size={16}
                      color="#525F7F"
                      style={{ textAlign: "center", fontFamily: 'open-sans-regular' }}
                    >
                      {nerdProfiles.bios[0].longDescription}
                    </Text>
                    <Button
                      color="transparent"
                      textStyle={{
                        color: "#233DD2",
                        fontWeight: "500",
                        fontSize: 16, 
                        fontFamily: 'open-sans-regular'
                      }}
                    >
                      Show more
                    </Button>
                  </Block>
                  <Block
                    row
                    style={{ paddingVertical: 14 }}
                    space="between"
                  >
                    <Text bold size={16} color="#525F7F" style={{ marginTop: 3 }}>
                      Video Appearances
                    </Text>
                    <Button
                      small
                      color="transparent"
                      textStyle={{ color: "#5E72E4", fontSize: 14 }}
                    >
                      View all
                    </Button>
                  </Block>
                    <Block style={{ marginHorizontal: theme.SIZES.BASE }}>
                      <FlatList 
                      style={styles.flatlist}
                      keyExtractor={this.keyExtractor}
                      data={nerdProfiles.bios[0].videos}
                      renderItem={this.renderVideoItem}
                      horizontal={true}
                      showsHorizontalScrollIndicator={false}
                      />
                    </Block>
                    <Block
                    row
                    style={{ paddingVertical: 14 }}
                    space="between"
                  >
                    <Text bold size={16} color="#525F7F" style={{ marginTop: 3 }}>
                      Articles Written
                    </Text>
                    <Button
                      small
                      color="transparent"
                      textStyle={{ color: "#5E72E4", fontSize: 14 }}
                    >
                      View all
                    </Button>
                  </Block>
                    <Block style={{ marginHorizontal: theme.SIZES.BASE }}>
                      <FlatList 
                      style={styles.flatlist}
                      keyExtractor={this.keyExtractor}
                      data={nerdProfiles.bios[0].articles}
                      renderItem={this.renderArticleItem}
                      horizontal={true}
                      showsHorizontalScrollIndicator={false}
                      />
                    </Block>
                  <Block
                    row
                    style={{ paddingVertical: 14 }}
                    space="between"
                  >
                    <Text bold size={16} color="#525F7F" style={{ marginTop: 3 }}>
                      Podcast Appearances
                    </Text>
                    <Button
                      small
                      color="transparent"
                      textStyle={{ color: "#5E72E4", fontSize: 14 }}
                    >
                      View all
                    </Button>
                  </Block>
                  <Block
                    row
                    style={{ paddingVertical: 14 }}
                    space="between"
                  >
                    <Text bold size={16} color="#525F7F" style={{ marginTop: 3 }}>
                      Live Appearances
                    </Text>
                    <Button
                      small
                      color="transparent"
                      textStyle={{ color: "#5E72E4", fontSize: 14 }}
                    >
                      View all
                    </Button>
                  </Block>
                  <Block
                    row
                    style={{ paddingVertical: 14 }}
                    space="between"
                  >
                    <Text bold size={16} color="#525F7F" style={{ marginTop: 3 }}>
                      Academic Work
                    </Text>
                    <Button
                      small
                      color="transparent"
                      textStyle={{ color: "#5E72E4", fontSize: 14 }}
                    >
                      View all
                    </Button>
                  </Block>
                </Block>
              </Block>
              <Block style={{ marginBottom: 25 }}/>
            </ScrollView>
          </ImageBackground>
        </Block>
      </Block>
    );
  }
}

NerdList 屏幕(第一个屏幕)

import React from "react";
import { Dimensions } from "react-native";

import { createStackNavigator } from "@react-navigation/stack";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";

// screens
import Feed from "../screens/Feed";
// import Onboarding from "../screens/Onboarding";
import Pro from "../screens/Pro";
import Profile from "../screens/Profile";
import Register from "../screens/Register";
import Elements from "../screens/Elements";
import Articles from "../screens/Articles";
import Search from "../screens/Search";
import Cart from "../screens/Cart";
import NerdList from "../screens/NerdList";

// settings
import SettingsScreen from "../screens/Settings";
import AgreementScreen from "../screens/Agreement";
import PrivacyScreen from "../screens/Privacy";
import AboutScreen from "../screens/About";
import NotificationsScreen from "../screens/Notifications";
// Notifications
import PersonalNotifications from "../screens/PersonalNotifications";
import SystemNotifications from "../screens/SystemNotifications";

// drawer
import CustomDrawerContent from "./Menu";

// header for screens
import { Icon, Header } from "../components";
import { argonTheme, tabs } from "../constants";
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";


const { width } = Dimensions.get("screen");

export const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();

function NotificationsStack() {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ color }) => {
          let iconName;
          if (route.name === "Personal") {
            iconName = "user";
          } else if (route.name === "System") {
            iconName = "database";
          } else if (route.name === "NerdList") {
            iconName = "user"
          }
          // You can return any component that you like here!
          return (
            <Icon
              name={iconName}
              family="entypo"
              size={22}
              color={color}
              style={{ marginTop: 10 }}
            />
          );
        }
      })}
      tabBarOptions={{
        activeTintColor: argonTheme.COLORS.PRIMARY,
        inactiveTintColor: "gray",
        labelStyle: {
          fontFamily: "open-sans-regular"
        }
      }}
    >
      <Tab.Screen name="Personal" component={PersonalNotifications} navigation />
      <Tab.Screen name="System" component={SystemNotifications} />
      <Tab.Screen name="NerdList" component={NerdList} />

    </Tab.Navigator>
  );
}

function BottomTabStack() {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ color }) => {
          let iconName;
          if (route.name === "Feed") {
            iconName = "user";
          } else if (route.name === "System") {
            iconName = "database";
          } else if (route.name === "NerdList") {
            iconName = "user"
          }
          // You can return any component that you like here!
          return (
            <Icon
              name={iconName}
              family="entypo"
              size={22}
              color={color}
              style={{ marginTop: 10 }}
            />
          );
        }
      })}
      tabBarOptions={{
        activeTintColor: argonTheme.COLORS.PRIMARY,
        inactiveTintColor: "gray",
        labelStyle: {
          fontFamily: "open-sans-regular"
        }
      }}
    >
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="System" component={SystemNotifications} />
      <Tab.Screen name="NerdList" component={NerdList} />

    </Tab.Navigator>
  );
}

function ElementsStack() {
  return (
    <Stack.Navigator mode="card" headerMode="screen">
      <Stack.Screen
        name="Elements"
        component={Elements}
        options={{
          header: ({ navigation, scene }) => (
            <Header title="Elements" navigation={navigation} scene={scene} />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
    </Stack.Navigator>
  );
}

function NerdListStack() {
  return (
    <Stack.Navigator mode="card" headerMode="screen">
      <Stack.Screen
        name="NerdList"
        component={NerdList}
        options={{
          header: ({ navigation, scene }) => (
            <Header title="NerdList" navigation={navigation} scene={scene} />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
      <Stack.Screen
        name="Profile"
        component={Profile} 
        options={{
          header: ({ navigation, scene }) => (
            <Header
              transparent
              white
              title="Profile"
              navigation={navigation}
              scene={scene}
              back={true}
            />
          ),
          cardStyle: { backgroundColor: "#FFFFFF" },
          headerTransparent: true
        }}
      />
    </Stack.Navigator>
  );
}

function SettingsStack() {
  return (
    <Stack.Navigator mode="card" headerMode="screen">
      <Stack.Screen
        name="Settings"
        component={SettingsScreen}
        options={{
          header: ({ navigation, scene }) => (
            <Header title="Settings" scene={scene} navigation={navigation} />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
      <Stack.Screen
        name="Agreement"
        component={AgreementScreen}
        options={{
          header: ({ navigation, scene }) => (
            <Header
              back
              title="Agreement"
              scene={scene}
              navigation={navigation}
            />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
      <Stack.Screen
        name="Privacy"
        component={PrivacyScreen}
        options={{
          header: ({ navigation, scene }) => (
            <Header
              back
              title="Privacy"
              scene={scene}
              navigation={navigation}
            />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
      <Stack.Screen
        name="About"
        component={AboutScreen}
        options={{
          header: ({ navigation, scene }) => (
            <Header back title="About" scene={scene} navigation={navigation} />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
      <Stack.Screen
        name="NotificationsSettings"
        component={NotificationsScreen}
        options={{
          header: ({ navigation, scene }) => (
            <Header
              back
              title="Notifications"
              scene={scene}
              navigation={navigation}
            />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
      <Stack.Screen
        name="Cart"
        component={Cart}
        options={{
          header: ({ navigation, scene }) => (
            <Header
              back
              title="Shopping Cart"
              scene={scene}
              navigation={navigation}
            />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
      <Stack.Screen
        name="Notifications"
        component={NotificationsStack}
        options={{
          header: ({ navigation, scene }) => (
            <Header
              back
              title="Notifications"
              scene={scene}
              navigation={navigation}
            />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
    </Stack.Navigator>
  );
}

function ArticlesStack() {
  return (
    <Stack.Navigator mode="card" headerMode="screen">
      <Stack.Screen
        name="Articles"
        component={Articles}
        options={{
          header: ({ navigation, scene }) => (
            <Header title="Articles" navigation={navigation} scene={scene} />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
    </Stack.Navigator>
  );
}

function ProfileStack() {
  return (
    <Stack.Navigator initialRouteName="Profile" mode="card" headerMode="screen">
      <Stack.Screen
        name="Profile"
        component={Profile} 
        options={{
          header: ({ navigation, scene }) => (
            <Header
              transparent
              white
              title="Profile"
              navigation={navigation}
              scene={scene}
              back={true}
            />
          ),
          cardStyle: { backgroundColor: "#FFFFFF" },
          headerTransparent: true
        }}
      />
      <Stack.Screen
        name="Cart"
        component={Cart}
        options={{
          header: ({ navigation, scene }) => (
            <Header
              back
              title="Shopping Cart"
              navigation={navigation}
              scene={scene}
            />
          ),
          cardStyle: { backgroundColor: "#FFFFFF" }
        }}
      />
      <Stack.Screen
        name="Notifications"
        component={NotificationsStack}
        options={{
          header: ({ navigation, scene }) => (
            <Header
              back
              title="Notifications"
              navigation={navigation}
              scene={scene}
            />
          ),
          cardStyle: { backgroundColor: "#FFFFFF" }
        }}
      />
    </Stack.Navigator>
  );
}

function FeedStack() {
  return (
    <Stack.Navigator mode="card" headerMode="screen">
      <Stack.Screen
        name="Feed"
        component={BottomTabStack}
        options={{
          header: ({ navigation, scene }) => (
            <Header
              title="Feed"
              navigation={navigation}
              scene={scene}
            />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
      <Stack.Screen
        name="Search"
        component={Search}
        options={{
          header: ({ navigation, scene }) => (
            <Header title="Search" back navigation={navigation} scene={scene} />
          ),
          cardStyle: { backgroundColor: "#F8F9FE" }
        }}
      />
    </Stack.Navigator>
  );
}

function AppStack() {
  return (
    <Drawer.Navigator
      style={{ flex: 1 }}
      drawerContent={props => <CustomDrawerContent {...props} />}
      drawerStyle={{
        backgroundColor: "white",
        width: width * 0.8
      }}
      drawerContentOptions={{
        activeTintcolor: "white",
        inactiveTintColor: "#000",
        activeBackgroundColor: "transparent",
        itemStyle: {
          width: width * 0.75,
          backgroundColor: "transparent",
          paddingVertical: 16,
          paddingHorizonal: 12,
          justifyContent: "center",
          alignContent: "center",
          alignItems: "center",
          overflow: "hidden"
        },
        labelStyle: {
          fontSize: 18,
          marginLeft: 12,
          fontWeight: "normal"
        }
      }}
      initialRouteName="Feed"
    >
      <Drawer.Screen name="Feed" component={FeedStack} />
      <Drawer.Screen name="Profile" component={ProfileStack} />
      <Drawer.Screen name="Account" component={Register} />
      <Drawer.Screen name="Elements" component={ElementsStack} />
      <Drawer.Screen name="Articles" component={ArticlesStack} />
      <Drawer.Screen name="Settings" component={SettingsStack} />
      <Drawer.Screen name="NerdList" component={NerdListStack} />
    </Drawer.Navigator>
  );
}

export default function OnboardingStack() {
  return (
    <Stack.Navigator mode="card" headerMode="none">
      <Stack.Screen
        name="Onboarding"
        component={Pro}
        option={{
          headerTransparent: true
        }}
      />
      <Stack.Screen name="App" component={AppStack} />
    </Stack.Navigator>
  );
}

【问题讨论】:

  • 你能把Profile屏幕的完整代码贴出来吗?
  • 没问题,我刚刚添加了配置文件屏幕代码。
  • 看起来不错。您的导航器配置如何?你也可以发一下吗?
  • @satya164 刚刚添加了导航器屏幕。有一些未使用的屏幕的导入,这个屏幕是一个正在进行中的工作。 NerdListStack 包含 NerdList 屏幕,它应该导航到 Profile 屏幕并传递参数。
  • 因此它看起来像嵌套在另一个名为Profile 的屏幕中,在这种情况下,您需要以不同的方式传递参数。请参阅此处的示例reactnavigation.org/docs/…navigation.navigate('Profile' /* 抽屉中的屏幕名称 /, { screen: 'Profile' / 堆栈中的屏幕名称 */, 参数 } });

标签: reactjs react-native react-navigation


【解决方案1】:

正如@satya164 在此处的评论中指出的那样,问题在于我错误地将参数传递给嵌套导航器。我试图通过以下方式传递参数:

onPress={() => this.props.navigation.navigate('Profile', {test: 'Hello'})}

将参数传递给嵌套导航器的正确方法是:

onPress={() => this.props.navigation.navigate('Profile', {screen: 'Profile', params: {test: 'name'}})}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 2018-11-14
    • 2019-04-28
    • 2023-03-20
    • 2019-11-07
    • 2022-11-11
    • 1970-01-01
    • 2019-03-03
    相关资源
    最近更新 更多