You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,该怎么解决?


解决思路与方案

问题根源

  1. 状态覆盖与异步更新:直接用setUserInfo({data: user.data })会覆盖原有对象的location属性,且useState是异步更新,立刻读取可能拿不到最新值。
  2. Context重复渲染:在两个分支分别渲染AuthContext.Provider,token切换时会重建Provider,可能导致子组件拿到旧的上下文值。
  3. 状态读取方式错误:子组件若未通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:20:53