为什么我得到 Render Error undefined is not an object (evaluating 'listing.image')?

Why am I getting Render Error undefined is not an object (evaluating 'listing.image')?

我对 React Native 比较陌生,我知道我的问题可能很小。我正在跟踪与 Mosh Hamedani 一起构建 React Native 应用程序,我已经达到了他的代码与他一起工作的地步,但似乎并没有与我一起工作,相反,它正在抛出

Render Error
undefined is not an object (evaluating 'listing.image')

我看了很多类似的问题,都解决了,但我还是搞不清楚自己的情况。我在下面包含了据信会产生此错误的组件:

import React from "react";
import { Image, StyleSheet, View } from "react-native";

import colors from "../config/colors";
import ListItem from "../components/lists/ListItem";
import Text from "../components/Text";

function ListingDetailsScreen({ route }) {
  const listing = route.params;

  return (
    <View>
      <Image source={listing.image} style={styles.image} /> //I don't get what's wrong here.
      <View style={styles.detailsContainer}>
        <Text style={styles.title}>{listing.title}</Text>
        <Text style={styles.price}>ZAR {listing.price}</Text>
        <View style={styles.sellerContainer}>
          <ListItem
            image={require("../assets/products-images/chair.jpg")}
            title="Firm Name"
            subTitle="5 Listings"
          />
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  detailsContainer: {
    padding: 20,
  },

  image: {
    width: "100%",
    height: 300,
  },

  price: {
    color: colors.secondary,
    fontWeight: "bold",
    fontSize: 20,
    marginVertical: 10,
  },

  sellerContainer: {
    marginVertical: 40,
  },

  title: {
    fontSize: 24,
    fontWeight: "500",
  },
});

export default ListingDetailsScreen;

消耗ListingDetails的组件如下所示:

import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { TransitionPresets } from "@react-navigation/stack";

import ListingDetailsScreen from "../screens/ListingDetailsScreen";
import ListingsScreen from "../screens/ListingsScreen";

const Stack = createStackNavigator();

const FeedNavigator = () => (
  <Stack.Navigator
    initialRouteName="ListingDetails"
    screenOptions={() => ({
      gestureEnabled: true,
      headerShown: false,
      ...TransitionPresets.ModalPresentationIOS,
    })}
  >
    <Stack.Screen name="Listings" component={ListingsScreen} />
    <Stack.Screen name="ListingDetails" component={ListingDetailsScreen} />
  </Stack.Navigator>
);

export default FeedNavigator;

对象 列表 在 return 时尚未加载。尝试使用 useEffect() 挂钩和 useState() 挂钩,并在 return 区域查询对象是否已加载。

示例:

import React, { useEffect, useState } from "react";   // new imports
import { Image, StyleSheet, View } from "react-native";

import colors from "../config/colors";
import ListItem from "../components/lists/ListItem";
import Text from "../components/Text";

function ListingDetailsScreen({ route }) {
  const [listing, setListing] = useState();   // declare the var with useState


useEffect(() => {             // useEffect
  setListing(route.params);
}, [route]);

  return (
    {listing ? (      // conditional operator 
     <View>
        <Image source={listing.image} style={styles.image} /> //I don't get what's wrong here.
        <View style={styles.detailsContainer}>
          <Text style={styles.title}>{listing.title}</Text>
          <Text style={styles.price}>ZAR {listing.price}</Text>
          <View style={styles.sellerContainer}>
            <ListItem
              image={require("../assets/products-images/chair.jpg")}
              title="Firm Name"
              subTitle="5 Listings"
            />
          </View>
        </View>
      </View>
    ) : (
      null  // maybe you can add an spinner or div here to indicate data is loading
    )}   
  );
}

更多信息请访问:

useState() -> https://reactjs.org/docs/hooks-state.html

useEffect() -> https://reactjs.org/docs/hooks-effect.html

条件渲染 -> https://reactjs.org/docs/conditional-rendering.html#inline-if-else-with-conditional-operator

我找到了这个问题的答案,答案就在FeedNavigator部分。我已经设置了 initialRouteName="ListingDetails" 这阻止了默认路由。

import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { TransitionPresets } from "@react-navigation/stack";

import ListingDetailsScreen from "../screens/ListingDetailsScreen";
import ListingsScreen from "../screens/ListingsScreen";

const Stack = createStackNavigator();

const FeedNavigator = () => (
  <Stack.Navigator
    // initialRouteName="ListingDetails" /* Removed this line and everything worked  as expected */
    screenOptions={() => ({
      gestureEnabled: true,
      headerShown: false,
      ...TransitionPresets.ModalPresentationIOS,
    })}
  >
    <Stack.Screen name="Listings" component={ListingsScreen} />
    <Stack.Screen name="ListingDetails" component={ListingDetailsScreen} />
  </Stack.Navigator>
);

export default FeedNavigator;