React Native中React.Context获取userInfo状态为null的问题
问题
我尝试在自己创建的全局状态管理对象中设置数据,状态定义如下:
const [isloggedIn, setIsLoggedIn] = useState(false); const [token, setToken] = useState(undefined); const [userInfo, setUserInfo] = useState({ data: "", location: "", });
store定义:
const store = useMemo( () => ({ authToken: [token, setToken], logInfo: [isloggedIn, setIsLoggedIn], userData: [userInfo, setUserInfo], }), [token, isloggedIn, userInfo], );
我已经把store通过AuthContext.Provider提供给Auth导航栈和Main导航栈,但尝试通过userInfo.data设置数据时得到null。不过在导航组件内执行相同操作却能成功。另外,用setUserInfo({data: user.data })设置后,导航中获取到的userInfo仍然是null。
导航代码如下:
if (token) { return ( <AuthContext.Provider value={store}> <MainNavigationStack /> </AuthContext.Provider> ); } return ( <AuthContext.Provider value={store}> <AuthNavigationStack /> </AuthContext.Provider> );
现在在导航组件和Auth页面中用console.log输出的userInfo都是null,该怎么解决?
解决思路与方案
问题根源
- 状态覆盖与异步更新:直接用
setUserInfo({data: user.data })会覆盖原有对象的location属性,且useState是异步更新,立刻读取可能拿不到最新值。 - Context重复渲染:在两个分支分别渲染
AuthContext.Provider,token切换时会重建Provider,可能导致子组件拿到旧的上下文值。 - 状态读取方式错误:子组件若未通过Context读取
userData,而是依赖局部变量,会拿到初始值或旧值。
具体修复步骤
正确更新userInfo(避免覆盖)
更新时保留原对象的其他属性,使用函数式更新确保拿到最新状态:// 错误写法:丢失location属性 setUserInfo({data: user.data }); // 正确写法:展开原有对象,仅修改目标字段 setUserInfo(prevState => ({ ...prevState, data: user.data }));统一Context包裹
将AuthContext.Provider提到分支外部,保证导航栈切换时Context的稳定性:return ( <AuthContext.Provider value={store}> {token ? <MainNavigationStack /> : <AuthNavigationStack />} </AuthContext.Provider> );子组件正确读取Context
子组件必须通过useContext获取全局状态,不能依赖局部变量:import { useContext } from 'react'; import AuthContext from './path-to-your-context'; const TargetComponent = () => { const { userData } = useContext(AuthContext); const [userInfo] = userData; console.log(userInfo); // 此处可获取最新状态 return <div>{userInfo.data}</div>; };监听状态更新
若在异步操作(如登录请求)后更新状态,用useEffect监听状态变化来处理后续逻辑:useEffect(() => { if (userInfo.data) { // 处理userInfo更新后的业务逻辑 } }, [userInfo]);
内容的提问来源于stack exchange,提问作者Harsh Mishra
相关产品推荐
相关产品推荐

