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

React Native中使用Context API获取userId返回undefined的问题

问题根源分析

你遇到的value.id为undefined的核心原因是重复定义了Context Provider,且两次Provider的value结构不一致,导致Consumer拿到的上下文对象和你预期的完全不同:

  1. 你在UserProvider.js里已经封装了一个标准的Provider,它的value是this.state,结构为{ id: '' }
  2. 但你又在别处单独写了<UserContext.Provider value={{state:this.state.id}}>,这个Provider会覆盖之前的上下文,此时传入的value结构变成了{ state: 你的id值 }
  3. 所以在Consumer里你试图获取value.id,但这个属性根本不存在,自然返回undefined(正确的取值应该是value.state,但这是不规范的写法)
修正方案

第一步:统一使用封装好的UserProvider组件

不要再单独使用<UserContext.Provider>,而是用你定义的UserProvider来包裹需要共享上下文的组件树(比如根组件或导航器):

// 比如在App.js里
import UserProvider from './store/UserProvider';
import YourNavigator from './YourNavigator';

export default function App() {
  return (
    <UserProvider>
      {/* 所有需要访问UserContext的组件都放在这个Provider内部 */}
      <YourNavigator />
    </UserProvider>
  );
}

第二步:完善UserProvider的状态更新能力(可选但推荐)

如果后续需要修改用户ID,建议在Provider内添加更新方法,方便子组件调用:

// store/UserProvider.js
import React, { createContext, Component } from "react";

// 初始化Context时可以定义默认值,包含状态和方法
export const UserContext = createContext({ 
  id: '', 
  setUserId: () => {} 
});

class UserProvider extends Component {
  state = { id: '', };

  // 添加更新用户ID的方法
  setUserId = (userId) => {
    this.setState({ id: userId });
  };

  render() {
    // 将状态和方法一起传入value,让子组件既能读又能改
    return (
      <UserContext.Provider value={{ ...this.state, setUserId: this.setUserId }}>
        {this.props.children}
      </UserContext.Provider>
    );
  }
}

export default UserProvider;

第三步:在Consumer中正确获取上下文

现在使用统一的UserProvider后,上下文结构回到{ id: '', setUserId: ... },此时value.id就能正确拿到值(初始为空字符串,不是undefined):

类组件写法(Consumer方式)

import { UserContext } from './store/UserProvider';
// 其他必要导入...

class YourProfileComponent extends Component {
  render() {
    return (
      <UserContext.Consumer>
        {(value) => {
          console.log("Context Id: ", value.id); 
          return (
            <ScrollView style={styles.container}>
              <View style={[GlobalInclude.container, { marginTop:32 }]}>
                <TouchableOpacity 
                  style={[ styles.button, styles.button1, { marginBottom:32 } ]} 
                  onPress={() => {
                    this.props.navigation.navigate('ModifProfil', {id: value.id})
                  }}
                >
                  <Text style={styles.textBtn}>MODIFIER MON PROFIL</Text>
                  <Icon style={{ }} name="chevron-right" size={18} color="#000" />
                </TouchableOpacity>
              </View>
            </ScrollView>
          );
        }}
      </UserContext.Consumer>
    );
  }
}

函数组件写法(useContext钩子更简洁)

import { useContext } from 'react';
import { UserContext } from './store/UserProvider';
// 其他必要导入...

function YourProfileComponent({ navigation }) {
  const { id } = useContext(UserContext);
  console.log("Context Id: ", id);

  return (
    <ScrollView style={styles.container}>
      <View style={[GlobalInclude.container, { marginTop:32 }]}>
        <TouchableOpacity 
          style={[ styles.button, styles.button1, { marginBottom:32 } ]} 
          onPress={() => navigation.navigate('ModifProfil', {id})}
        >
          <Text style={styles.textBtn}>MODIFIER MON PROFIL</Text>
          <Icon style={{ }} name="chevron-right" size={18} color="#000" />
        </TouchableOpacity>
      </View>
    </ScrollView>
  );
}

额外检查

确保你的Consumer组件确实在UserProvider的包裹范围内,如果组件树层级错误(Consumer在Provider外面),会使用Context的默认值{ id: '' },但不会返回undefined,所以这个情况概率较低。

内容的提问来源于stack exchange,提问作者Jats1596

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 22:08:12