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
相关产品推荐
相关产品推荐

