React Native组件渲染前Context中userId无法访问的问题求助
React Native Context userId 未就绪导致 useEffect 请求失败解决方案
问题本质
Dashboard组件挂载时,useEffect依赖空数组仅执行一次,但此时Login组件还未完成Context中userId的更新,导致请求时userId为空,触发后端404错误。日志中Token能显示是因为日志输出的是组件渲染时的状态快照,而非useEffect执行瞬间的状态。
具体修复方案
1. 给 useEffect 添加正确依赖并增加空值判断
修改Dashboard组件中的useEffect,将id加入依赖数组,同时仅当id存在时才发起请求:
// 获取帖子的useEffect useEffect(() => { if (id) { getPostsFromFollowingUsers(); } }, [id]); // 获取头像的useEffect同理,依赖token并判断非空 useEffect(() => { if (token) { getProfilePicture(); } }, [token]);
2. 优化Login组件的状态更新与跳转时机
setState是异步操作,直接跳转可能导致Context状态未同步完成,需确保状态更新后再跳转:
const loginUser = async (): Promise<ISuccessFullResponse | boolean> => { try { const body = { email, password }; const url = REMOTE_SERVER + '/authentication/loginUser'; const response = await fetch(url, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }); // 补上漏掉的response解析步骤 const loggedUser = await response.json(); const id = loggedUser.data.user._id; const name = loggedUser.data.user.userName; // 更新Context状态 setToken(loggedUser.data.token); setUserId(id); setUserName(name); setIsAuthenticated(true); // 用setTimeout确保状态更新完成后跳转 setTimeout(() => { navigation.navigate('Dashboard'); }, 0); return loggedUser; } catch (error) { console.log(error); return false; } };
更可靠的方式是用useEffect监听认证状态跳转:
// Login组件中添加 useEffect(() => { if (isAuthenticated) { navigation.navigate('Dashboard'); } }, [isAuthenticated, navigation]);
3. 优化Context初始值(可选)
替换类型断言,给Context设置合法初始值,提升类型安全性:
export const AuthContext = createContext<AuthContextType>({ isAuthenticated: false, setIsAuthenticated: () => {}, token: '', setToken: () => {}, userId: '', setUserId: () => {}, userName: '', setUserName: () => {} });
修复效果
修改后,Login组件完成Context状态更新后才会跳转,Dashboard组件会在userId就绪时自动触发请求,不会再出现空userId导致的404错误。
内容的提问来源于stack exchange,提问作者user16604664
相关产品推荐
相关产品推荐

