useEffect和useState未在提取中设置值

时间:2020-07-24 12:38:47

标签: react-native fetch

我有一个杂志风格的应用程序,它有一个索引页面-名为HomeScreen的组件-(带有文章列表)和一个详细信息页面-名为Details的组件-(带有完整文章); 在它们的上方,我有一个Home组件,它是机器人的堆栈导航。

家庭组件

 const Home = ({}) => {
  return (
    <Stack.Navigator initialRouteName="Home">
      <Stack.Screen name="Home" component={HomeScreen} options={HeaderOption} />
      <Stack.Screen
        name="Details"
        component={DetailsScreen}
        options={HeaderOption}
      />
    </Stack.Navigator>
  );
};
export default Home;

然后(相同的文件)获得了HomeScreen组件,该组件可以(正确地)呈现文章列表,它使用useEffect从API中获取文章

function HomeScreen({ navigation }) {
  const [article, setArticles] = useState();
  const [loadingArticle, setLoading] = useState(false);
  useEffect(() => {
    console.log('start Fetching');
    fetchTitles();
  }, []);
const fetchTitles = () => {
    fetch('myURL', {
      method: 'GET',
    })
      .then((response) => response.json())

      .then((responseData) => {
        setArticles(responseData);
      })
      .finally(() => setLoading(false));
  };

  const { state } = useContext(AuthContext);
return (
    <View
      style={{
        flex: 1,
        paddingTop: Constants.HEIGTH,
        backgroundColor: Constants.MAIN_GREEN,
      }}
    >
      <LogoHeader title="TITOLO APP" isHome={true} navigation={navigation} />
      <View style={{ ...styles.container }}>
        <FlatList
          data={article}
          keyExtractor={(item) => item.id.toString()}
          renderItem={({ item }) => (
            <TouchableOpacity
              onPress={() =>
                navigation.navigate('Details', {
                  itemId: item.id,
                })
              }
            >
              <Card>
                <Card.Content>
                  <HTML
                    html={item.title.rendered}
                    baseFontStyle={{ fontSize: 20, color: '#adadad' }}
                  />

                  <Paragraph>
                    Published on {moment(item.date).format('LL')}
                  </Paragraph>
                </Card.Content>
                <Card.Cover source={{ uri: item.jetpack_featured_media_url }} />
                <Card.Content>
                  <HTML
                    html={item.excerpt.rendered}
                    imagesMaxWidth={Dimensions.get('window').width}
                  />
                </Card.Content>
              </Card>
            </TouchableOpacity>
          )}
        />
      </View>
    </View>
  );
}

当我单击该文章时,即使responseData是正确的,我也可以正确到达带有正确传递的id的Details,但singleArticle为“ null”:

 function DetailsScreen({ route, navigation }) {
      const { state } = useContext(AuthContext);
      const [singleArticle, setSingleArticle] = useState(null);
      const [loadingArticle, setLoadingSingle] = useState(false);
      useEffect(() => {
       setLoadingSingle(true);
       console.log(loadingArticle); //return false (???)
        fetchSingle();
      }, []);
    
      const fetchSingle = () => {
        console.log('get_single');
        fetch(
          'myURLgetsingle?' +
            route.params.itemId,
    
          {
            method: 'GET',
          }
        )
          .then((response) => response.json())
    
          .then((responseData) => {
            console.log('setting');
    
            console.log(responseData); //return the values i need
            setSingleArticle(responseData);
            console.log(singleArticle); //return null
          })
          .finally(() => setLoadingSingle(false));
      };
    
      console.log(singleArticle.title.rendered);
      return (
        <View
          style={{
            flex: 1,
            paddingTop: Constants.HEIGTH,
            backgroundColor: Constants.MAIN_GREEN,
          }}
        >
          <LogoHeader title="" isHome={false} navigation={navigation} />
          <Card style={{ ...styles.container, padding: 10 }}>
            <Card.Content>
              <Title>{singleArticle.title.rendered}</Title>
              <Paragraph></Paragraph>
            </Card.Content>
          </Card>
        </View>
      );
    }

我认为我缺少对react native的一些基本用法,我可以通过任何方式对其进行修复吗? 谢谢

1 个答案:

答案 0 :(得分:1)

Ciao,这对于Hooks来说是完全正常的。当您致电setSingleArticle(responseData);并尝试在下一行登录singleArticle时,几乎可以肯定您获得了null的值。发生这种情况是因为setSingleArticle是异步的,并且在Hooks中,您没有这样的回调:

setSingleArticle(responseData, () => {
  // here I'm sure that singleArticle was setted
  // with Hooks this is impossible to do!
});

因此,结果是,在console.log(singleArticle.title.rendered);行中,您应该收到类似“无法获取属性标题为null”的错误。由于您的singleArticle值来自提取,因此您可以尝试修改singleArticle的默认值,例如:

const [singleArticle, setSingleArticle] = useState({title: {rendered: ''}});

通过这种初始化,console.log(singleArticle.title.rendered);不会失败。此行<Title>{singleArticle.title.rendered}</Title>

同样

编辑

对于加载样式,您可以执行以下操作:

<Title>{singleArticle.title.rendered === '' ? "Loading..." : singleArticle.title.rendered}</Title>