React读取Context值报Cannot read properties of undefined错误
报错根因
触发Cannot read properties of undefined (reading 'name')错误有两个核心问题:
- 上层组件未传递对应上下文:
App.js中渲染<Home />时,仅包裹了ThemeContext.Provider,完全缺失UserContext.Provider的包裹,导致Home组件内调用useContext(UserContext)拿到的返回值为undefined,访问undefined.name直接抛出类型错误。 - Context用法错误:Home组件中同时混用
useContext钩子和UserContext.Consumer两种上下文获取方式,且Consumer组件要求子元素必须是接收上下文值、返回JSX的函数,直接在Consumer内写JSX节点属于语法错误,即使上下文传递正确也会触发渲染异常。
修复步骤
- 修改
App.js,在渲染Home组件的位置外层补上UserContext.Provider,将user状态作为value传入,保证Home组件可以获取到上下文值。 - 统一Home组件的上下文获取方式,删除冗余的
UserContext.Consumer嵌套,直接使用useContext拿到的user值渲染即可。
修正后代码
App.js
import React, { useState } from 'react' import Navigation from './Navigation' import ThemeContext from './ThemeContext' import UserContext from './UserContext' import Home from './Home' function App() { const [theme, setTheme] = useState({ variant: 'dark', toggleTheme: toggleTheme }) const [user, setUser] = useState({ name: "Alyssa" }) function toggleTheme() { setTheme(theme => ( { ...theme, variant: theme.variant === 'dark' ? 'light' : 'dark', } )) } return ( <> <ThemeContext.Provider value={theme}> <Navigation /> <UserContext.Provider value={user}> <Home /> </UserContext.Provider> </ThemeContext.Provider> </> ) } export default App
Home.js
import Card from 'react-bootstrap/Card' import Button from 'react-bootstrap/Button' import Alert from 'react-bootstrap/Alert' import UserContext from './UserContext' import { useContext } from 'react' function Home() { const user = useContext(UserContext) return ( <> <Alert variant="success">Welcome back, {user.name}!</Alert> <Card className="text-center col-md-10 mx-auto my-3"> <Card.Header>Featured</Card.Header> <Card.Body> <Card.Title>This is Our Featured Item</Card.Title> <Card.Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </Card.Text> <Button variant="primary">Click Here</Button> </Card.Body> </Card> </> ) } export default Home
可选优化:为了避免后续上下文传值异常导致页面崩溃,可以在访问name属性时增加兜底逻辑,例如写成
{user?.name || '游客'},即使上下文值异常也会显示默认内容,不会直接抛错。
内容的提问来源于stack exchange,提问作者Aquiles Bailo
相关产品推荐
相关产品推荐

