React native 在前台屏幕上更新全局状态时,即使屏幕处于后台,也会调用useFocusEffect挂钩
我正在开发一个本地项目。这个问题主要是关于我的项目中的钩子行为 我有几个屏幕。有一个共享数据&每个屏幕都可以更新数据。因此,我决定使用React native 在前台屏幕上更新全局状态时,即使屏幕处于后台,也会调用useFocusEffect挂钩,react-native,react-navigation,react-navigation-v5,React Native,React Navigation,React Navigation V5,我正在开发一个本地项目。这个问题主要是关于我的项目中的钩子行为 我有几个屏幕。有一个共享数据&每个屏幕都可以更新数据。因此,我决定使用context通过useStatehook托管数据。当一个屏幕设置MyData()时,所有屏幕都可以使用最新数据 我的数据上下文通过useStatehook托管共享数据: import React, {useState} from 'react'; const MyDataContext = React.createContext(); export cons
context
通过useState
hook托管数据。当一个屏幕设置MyData(
)时,所有屏幕都可以使用最新数据
我的数据上下文通过useState
hook托管共享数据:
import React, {useState} from 'react';
const MyDataContext = React.createContext();
export const MyDataProvider = ({children}) => {
const [myData, setMyData] = useState([]);
...
return (
<MyDataContext.Provider
value={{
myData,
setMyData,
}}>
{children}
</MyDataContext.Provider>
);
}
export default MyDataContext;
正如您所看到的,我有一个按钮,可以将用户导航到另一个屏幕。另一个屏幕具有与useFocusEffect
钩子相同的结构,它在钩子中处理和更新全局状态的数据
当我运行我的应用程序时,以下情况发生在我身上:
MyScreenOne
启动<调用code>useFocusEffect,通过setMyData()
setMyData()
,因此会发生重新渲染,此时不会再次调用MyScreenOne
的useFocusEffect
,这是很好的,也是意料之中的
MyScreenTwo
的按钮。在MyScreenTwo
上也会发生相同的过程:useFocusEffect
被调用,数据被处理和更新,并通过setMyData()
设置为全局状态。注意:MyScreenOne
现在不可见,并且在后台堆栈/内存中
MyScreenOne
的useFocusEffect
再次被调用,因为MyScreenOne
中的钩子再次更新了全局状态,内存中的屏幕再次被重新渲染
MyScreenOne
的useFocusEffect
被意外调用,现在会发生无休止的重新渲染
useFocusEffect
不应该只在屏幕可见时运行吗?为什么在重新渲染时也会调用背景屏幕的useFocusEffect
hook?如何实现我只需在每个屏幕上运行一次流程数据和更新数据,同时屏幕可见,所有屏幕都可以共享数据?UseFocuseEffect
不采用依赖关系数组。您需要传递文档中提到的useCallback
:
useFocusEffect(
React.useCallback(()=>{
//随便
}, [])
);
好的!谢谢!
import {useFocusEffect} from '@react-navigation/native';
import MyDataContext from '../context/MyDataContext';
const MyScreenOne = ({navigation})=> {
const {myData, setMyData} = useContext(MyDataContext);
useFocusEffect(() => {
console.log('################# Screen one is FOCUSED! ');
const updatedData = processData([...myData]);
// set my data
setMyData(updatedData);
return () => {
console.log('Screen one was unfocused');
};
}, []);//empty array to force code in hook only run once
return (<View>
<MyButton onPress={()=> navigation.navigate("MyScreenTwo")}>
...
</View>
)
}
...