React Native中如何延迟useEffect执行直到useSelector获取Redux存储数据
问题根因
- React的
setState是异步更新的,在同一个useEffect执行上下文内调用setId(userId)后,立刻读取id拿到的还是本次effect运行时的旧值(初始为空字符串),无法获取到刚设置的新值。 - 你的useEffect语法存在错误:依赖数组被写在了useEffect的回调函数括号外部,相当于没有传入依赖配置,会导致effect在每次组件渲染时都重复执行。
- 额外冗余的本地id状态完全没有必要,你可以直接使用useSelector拿到的
userId,不需要多转一层state存储。
最优解决方案(推荐)
直接移除多余的本地id状态,将userId作为useEffect的依赖项,判断userId有效值后再发起请求即可,修复后代码如下:
function Tasks_1 () { const userId = useSelector((state) => state.id); const [tasks, setTasks] = useState([]); useEffect(() => { // 只有userId有有效值时才执行请求逻辑 if (!userId) return; // 记得返回清理函数取消快照订阅,避免内存泄漏 const unsubscribe = db.collection('users').doc(userId).collection('tasks').onSnapshot((snapshot)=>{ const tempTasks = []; snapshot.forEach(doc => { tempTasks.push(doc.data()); }) setTasks(tempTasks); }); return () => unsubscribe(); }, [userId]); // 依赖项为userId,userId更新时才重新运行effect return ( ... ) }
若你需要保留本地id状态的修复方案
拆分为两个useEffect,第一个负责同步Redux的userId到本地id,第二个负责监听id变化后发起请求:
function Tasks_1 () { const [id, setId] = useState(''); const userId = useSelector((state) => state.id); const [tasks, setTasks] = useState([]); // 第一个effect:同步userId到本地state useEffect(() => { setId(userId); }, [userId]); // 第二个effect:监听id变化,有效值时发起请求 useEffect(() => { if (!id) return; const unsubscribe = db.collection('users').doc(id).collection('tasks').onSnapshot((snapshot)=>{ const tempTasks = []; snapshot.forEach(doc => { tempTasks.push(doc.data()); }) setTasks(tempTasks); }); return () => unsubscribe(); }, [id]); return ( ... ) }
内容的提问来源于stack exchange,提问作者Matt Laszcz
相关产品推荐
相关产品推荐

