React中UseContext未更新状态变量,始终保留旧值问题
React Context 数据更新不触发任务获取的解决方案
问题核心在于TasksProvider里的useEffect依赖项为空数组,仅在组件首次挂载时执行一次fetchTasks,后续username更新后不会重新触发请求。
修复步骤:
添加依赖项触发更新
将username加入useEffect的依赖数组,确保每次username变化时自动重新拉取任务:function TasksProvider({ children }) { const { username } = useContext(AccountContext); const [todos, setTodos] = useState([]); const fetchTasks = async () => { // 避免username为空时发起无效请求 if (!username) return; const result = await getAllTasks(username); setTodos(result); }; useEffect(() => { fetchTasks(); }, [username]); // 此处添加username作为依赖 return ( <TasksContext.Provider value={{ todos }}> {children} </TasksContext.Provider> ); }处理竞态条件(可选但推荐)
若存在用户快速切换场景,可能出现旧请求覆盖新请求结果的问题,可通过AbortController取消未完成请求:function TasksProvider({ children }) { const { username } = useContext(AccountContext); const [todos, setTodos] = useState([]); const fetchTasks = async (signal) => { if (!username) return; try { // 假设getAllTasks支持传入AbortSignal const result = await getAllTasks(username, signal); setTodos(result); } catch (err) { // 忽略请求被取消的错误 if (err.name !== 'AbortError') throw err; } }; useEffect(() => { const controller = new AbortController(); fetchTasks(controller.signal); // 组件卸载或username变更时取消请求 return () => controller.abort(); }, [username]); return ( <TasksContext.Provider value={{ todos }}> {children} </TasksContext.Provider> ); }同步修改
getAllTasks函数以支持信号参数:async function getAllTasks(username, signal) { const response = await fetch(`/api/tasks?username=${username}`, { signal }); return response.json(); }验证AccountContext更新逻辑
确保AccountContext中username在token更新时被正确设置,可添加日志验证:useEffect(() => { const user = Pool.getCurrentUser(); if (user) { setUserName(user.username); } else { // 用户登出时清空username,避免残留旧值 setUserName(null); } }, [token]);
补充说明
你的Context嵌套结构是正确的,TasksContext处于AccountContext内部,可正常接收其更新值,核心问题就是依赖项未正确配置。
内容的提问来源于stack exchange,提问作者Modi
相关产品推荐
相关产品推荐

