返回屏幕时未在 React Native 中调用 useEffect

IT技术 reactjs react-native use-effect
2021-05-17 02:41:47

你好吗。这是这个问题的场景。假设有 2 个屏幕可以简化操作。

  1. 进入 A 画面。useEffect of A 屏幕调用。
  2. 从 A 屏幕导航到 B 屏幕
  3. 从 B 导航回 A 屏幕。此时,不会调用 useEffect。

    function CompanyComponent(props) {
    
       const [roleID, setRoleID] = useState(props.user.SELECTED_ROLE.id)
    
       useEffect(()=>{ 
    
     // this called only once when A screen(this component) loaded,  
     // but when comeback to this screen, it doesn't called
       setRoleID(props.user.SELECTED_ROLE.id)
     }, [props.user])
    }
    

所以当再次回到 A 屏幕时,屏幕 A 的更新状态保持不变(不从props加载)

我没有更改屏幕 B 中的 props.user。但我认为 const [roleID, setRoleID] = useState(props.user.SELECTED_ROLE.id)至少应该调用这条线。

我正在使用 redux-persist。我认为这不是问题。对于导航,我使用这个

// to go first screen A, screen B
function navigate(routeName, params) {
    _navigator.dispatch(
        NavigationActions.navigate({
            routeName,
            params,
        })
    );
}
// when come back to screen A from B
function goBack() {
    _navigator.dispatch(
        NavigationActions.back()
    );
}

当屏幕出现时,我可以使用任何回调吗?我的代码有什么问题?

谢谢

4个回答

以下解决方案对我有用:

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

const ExampleScreen = (props) => {
    const isFocused = useIsFocused();

    useEffect(() => {
        console.log("called");
 
        // Call only when screen open or when back on screen 
        if(isFocused){ 
            getInitialData();
        }
    }, [props, isFocused]);

    const getInitialData = async () => {}    

    return (
        ......
        ......
    )
}

我用过react导航 5+

@react-navigation/native": "5.6.1"

当您从 A 导航到 B 时,组件 A 不会被销毁(它保留在导航堆栈中)。因此,当您返回时,代码不会再次运行。

也许是实现您想要使用导航生命周期事件(我假设您正在使用react-navigation的更好方法,即订阅didFocus事件并在组件聚焦时运行您想要的任何代码,例如

const unsubscribe = props.navigation.addListener('didFocus', () => {
    console.log('focussed');
});

不要忘记在适当的时候取消订阅,例如

// sometime later perhaps when the component is unmounted call the function returned from addListener. In this case it was called unsubscribe
unsubscribe();

当前版本的 React Navigation 提供了 useFocusEffect 钩子。这里

React Navigation 5 提供了一个 useFocusEffect 钩子,类似于 useEffect,唯一的区别是它只在当前屏幕聚焦时运行。检查文档https://reactnavigation.org/docs/use-focus-effect

 useFocusEffect(
    useCallback(() => {
      const unsubscribe = setRoleID(props.user.SELECTED_ROLE.id)
      return () => unsubscribe()
    }, [props.user])
  )