点击NewTab按钮后useEffect返回函数执行两次问题求助
问题分析与解决
为什么清理函数执行两次?
当你点击NewTab按钮,setNewTab(true)触发状态更新时:
- React会先执行上一次useEffect的清理函数,此时闭包捕获的
newTab是旧值false; - 接着执行新的useEffect,因为
newTab为true,调用navigation.goBack()导致当前组件卸载; - 组件卸载时,又会执行当前useEffect的清理函数,此时捕获的
newTab是新值true,所以出现两次执行的情况。
解决办法
方案一:用useRef跟踪最新状态值(解决闭包问题)
const App = () => { const [newTab, setNewTab] = useState(false); const newTabRef = useRef(newTab); // 实时同步最新的newTab值到ref useEffect(() => { newTabRef.current = newTab; }, [newTab]); useEffect(() => { if (newTab) { navigation.goBack(); } return () => { // 通过ref获取最新状态,避免闭包捕获旧值 if (!newTabRef.current) { // 清理redux数据 } }; }, [newTab, navigation]); return ( <View> <TouchableOpacity onPress={() => navigation.goBack()}> GoBack </TouchableOpacity> <TouchableOpacity onPress={() => { setNewTab(true); // 向Redux存储中推送数据的代码 }}> NewTab </TouchableOpacity> </View> ); }; export default App;
方案二:简化逻辑,直接在点击事件中调用返回
既然点击NewTab的核心目的是推送数据后返回,直接在点击事件里执行navigation.goBack(),省去useEffect中转,避免重复触发:
const App = () => { const [newTab, setNewTab] = useState(false); // 仅在组件正常卸载(点击GoBack按钮)时清理数据 useEffect(() => { return () => { if (!newTab) { // 清理redux数据 } }; }, [newTab]); return ( <View> <TouchableOpacity onPress={() => navigation.goBack()}> GoBack </TouchableOpacity> <TouchableOpacity onPress={() => { setNewTab(true); // 推送数据到Redux navigation.goBack(); // 直接在这里执行返回 }}> NewTab </TouchableOpacity> </View> ); }; export default App;
内容的提问来源于stack exchange,提问作者Mayur Vaghasiya
相关产品推荐
相关产品推荐

