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

React Native更新AuthContext的userInfo后子组件值变为undefined问题

React Native中AuthContext更新后HomeScreen的userInfo变为undefined的问题

我尝试在AuthContext.js中更新userInfo的值,但更新后HomeScreen中的userInfo变为undefined。Axios接口调用正常,已成功更新数据库且能获取到更新后的用户数据,但更新后始终报错:TypeError: Cannot read property 'username' of undefined。

AuthContext.js

export const AuthContext = createContext();

export const AuthProvider = ({children}) => {
    const [userInfo, setUserInfo] = useState('');

    const update =  async (formData,) => {
        await axios.post(`${BASE_URL}/user/update`, formData, {
            headers: {
                'Content-Type': 'multipart/form-data',
            },
        })
        .then(response => {
            let resInfo = response.data;
            setUserInfo(resInfo);
            console.log(userInfo);
            AsyncStorage.setItem('userInfo', JSON.stringify(resInfo));
        })
        .catch(e => {
            console.log(`Profile Update Error ${e}`)
        });
    }

    return (
        <AuthContext.Provider value={{ update, userInfo }}>
            {children}
        </AuthContext.Provider>
    )
}

HomeScreen.js

const Home = () => {
    const { update, userInfo } = useContext(AuthContext);

    const [username, setUsername] = useState(userInfo.users.username);

    useEffect(() => {
    }, [userInfo])

    return(
         <View style={{marginVertical: 5, flexDirection:'row'}}>
               <Text style={[styles.bodyText, {color: COLORS.primary,}]}>@</Text>
               <Text style={styles.bodyText}>{username}</Text>
         </View>
    )
}
export default Home;

问题原因及解决方案

1. 初始化值不匹配导致的首次/更新渲染报错

你将userInfo的初始值设为空字符串'',但接口返回的是包含users对象的结构。空字符串没有users属性,不管是首次渲染还是更新后,都会触发Cannot read property 'username' of undefined错误。

2. 状态同步逻辑错误

useState(userInfo.users.username)的初始值仅在组件首次渲染时生效,后续userInfo更新不会自动同步到username状态。


修改后的代码示例

调整AuthContext.js的初始值

export const AuthContext = createContext();

export const AuthProvider = ({children}) => {
    // 初始化为符合接口返回结构的空对象,避免属性读取报错
    const [userInfo, setUserInfo] = useState({ users: {} });

    const update =  async (formData,) => {
        try {
            const response = await axios.post(`${BASE_URL}/user/update`, formData, {
                headers: {
                    'Content-Type': 'multipart/form-data',
                },
            });
            const resInfo = response.data;
            setUserInfo(resInfo);
            AsyncStorage.setItem('userInfo', JSON.stringify(resInfo));
        } catch(e) {
            console.log(`Profile Update Error ${e}`);
        }
    }

    return (
        <AuthContext.Provider value={{ update, userInfo }}>
            {children}
        </AuthContext.Provider>
    )
}

调整HomeScreen.js的渲染逻辑(二选一)

方案一:直接使用可选链渲染(无需额外状态)
const Home = () => {
    const { update, userInfo } = useContext(AuthContext);

    return(
         <View style={{marginVertical: 5, flexDirection:'row'}}>
               <Text style={[styles.bodyText, {color: COLORS.primary,}]}>@</Text>
               {/* 可选链+默认值,避免undefined报错 */}
               <Text style={styles.bodyText}>{userInfo?.users?.username || ''}</Text>
         </View>
    )
}
export default Home;
方案二:通过useEffect同步状态
const Home = () => {
    const { update, userInfo } = useContext(AuthContext);
    const [username, setUsername] = useState('');

    useEffect(() => {
        // 监听userInfo变化,同步更新username
        if (userInfo?.users?.username) {
            setUsername(userInfo.users.username);
        }
    }, [userInfo])

    return(
         <View style={{marginVertical: 5, flexDirection:'row'}}>
               <Text style={[styles.bodyText, {color: COLORS.primary,}]}>@</Text>
               <Text style={styles.bodyText}>{username}</Text>
         </View>
    )
}
export default Home;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:25:13