1

我有一个屏幕调用 api 来获取一些数据,然后显示

我看到的一个问题是,当我离开屏幕(我使用的是 react-navigation 6.x)然后返回它时useEffect()不会被调用

从我到目前为止所阅读的内容来看,这取决于userId不改变的价值(我认为我需要围绕useEffect()钩子做更多的阅读才能更好地理解,也许有人会帮助解决这个问题)

import React, {useState, useEffect, useContext} from 'react';
import AppContext from '../../components/AppContext.js';

export const CreateNewEvent = () => {
  const globalContext = useContext(AppContext);
  const userId = globalContext.userInfo.id;

  useEffect(() => {
    const body = JSON.stringify({userId});
    fetch(eventTypesUrl, {
      method: 'POST',
      headers: {'Content-Type': 'application/json', Accept: 'application/json'},
      body: body,
    })
      .then(response => response.json())
      .then(json => setEventTypeData(json))
      .catch(error => console.error(error))
      .finally(() => setLoading(false));
    }, [userId]);

}

所以在我的场景中,我在屏幕 1 上(在这里我可以创建一个事件,请求获取所有事件类型并将它们加载到选择菜单中)

当我导航到屏幕 2(以创建事件类型)然后返回屏幕 1 时,useEffect()不会调用挂钩导致无法看到我刚刚创建的事件类型(希望这是有道理的).. 还请注意,任何之前在屏幕 1 中输入的数据仍然保留

我遇到了这篇似乎是我正在处理的帖子,只是有点不确定如何使用我的设置来实现

当我返回时,如何确保 Screen 2 进行 api 调用并且清除所有以前的表单数据?

谢谢

4

2 回答 2

2

React Navigation 的核心是在用户导航回该屏幕以进行性能优化时不会重新渲染屏幕,并避免不必要的重新渲染。

当需要时,它们提供了一个有用的钩子来检测屏幕何时聚焦并运行一些副作用。

让我们重构代码如下:

Top-level import 
import { useFocusEffect } from "@react-navigation/core";

// Run side effects when screen focused, navigated, or visited 

useFocusEffect(
    React.useCallback(() => {
 const body = JSON.stringify({userId});
    fetch(eventTypesUrl, {
      method: 'POST',
      headers: {'Content-Type': 'application/json', Accept: 'application/json'},
      body: body,
    })
      .then(response => response.json())
      .then(json => setEventTypeData(json))
      .catch(error => console.error(error))
      .finally(() => setLoading(false));
      

      return () => {
        // Run  somelogisx when user leave screen,
        // Cleaning caches or cancelling subscriptions

       
      };
    }, [userId]))



注意: React.useCallbackuseFocusEffectAPI 的一部分。React Navigation 团队试图通过 memoization 优化屏幕性能。

于 2022-01-07T14:44:15.193 回答
1

在 React Native 中,当您向前导航时,每个屏幕都会被推送到导航堆栈。

现在,当您向后导航时,会弹出前一个屏幕并显示堆栈中最顶层的屏幕。由于最上面的屏幕中没有任何东西(状态或道具)发生变化,因此不会重新渲染。

所以你必须做一些手工工作。

import { useIsFocused } from "@react-navigation/native";


const isFocused = useIsFocused();

isFocused 是布尔值

useEffect(() => {

 if (userId && isFocused) {
   // Code which you want to execute when screen is loaded first 
   // time(and after userId is initialised) or loaded after press of 
   // back button     
 }
 
    
}, [userId, isFocused]);
于 2022-01-07T14:50:30.143 回答