我正在尝试学习如何正确使用上下文和挂钩。当所有内容都在课堂上时,我就可以正常工作,当我将其拆分为其他无法找到上下文的课程时。这是我尝试过的。”
我已将我的应用包装在提供商中。
import React, {useContext} from 'react';
import Header from 'components/Header';
class App extends React.Component {
constructor () {
super();
this.state = {
firstName: "Bob",
lastName: "Joe",
}
}
const {firstName,lastName} = this.state;
return (
<UserContext.Provider value = {{firstName,lastName}}>
<Header/>
</UserContext.Provider>
)
}
然后在Header中,我创建了一个Navbar函数来尝试和使用它。
const UserContext = React.createContext();
class Header extends React.Component {
render() {
return (
<div className="header">
<NavBar/>
</div>
);
}
}
function NavBar () {
const {firstName,lastName} = useContext(UserContext);
}
return (
<nav className="navbar">
<span> Hello, {firstName} {lastName} </span>
</nav>
)
}
我不确定是什么问题。
当我在同一页面下全部使用它时,感觉很好。
我收到“名字”未定义的错误。我必须首先将其作为状态通过吗?
答案 0 :(得分:2)
您需要从UserContext
文件中导出App.js
后在其中创建文件,或创建一个新文件UserContext.js
,该文件将导出上下文。
从那里,您需要从声明UserContext
的文件中导入NavBar
。
而且似乎您在render()
组件中缺少App
。
例如)
UserContext.js
import {createContext} from 'react';
const UserContext = createContext();
export default UserContext;
App.js
import React from 'react';
import Header from 'components/Header';
import UserContext from './UserContext';
class App extends React.Component {
constructor () {
super();
this.state = {
firstName: "Bob",
lastName: "Joe",
}
}
render() {
const {firstName,lastName} = this.state;
return (
<UserContext.Provider value = {{firstName,lastName}}>
<Header/>
</UserContext.Provider>
)
}
}
components/Header.js
// other react imports omitted...
import UserContext from '../UserContext';
class Header extends React.Component {
render() {
return (
<div className="header">
<NavBar/>
</div>
);
}
}
function NavBar () {
const {firstName,lastName} = useContext(UserContext);
}
return (
<nav className="navbar">
<span> Hello, {firstName} {lastName} </span>
</nav>
)
}
此外,将整个this.state
对象作为上下文的值传递,而不是像{firstName, lastName}
那样进行结构分解,因为这会导致您的子组件在每次传递新值时都重新渲染对象引用。
所以推荐的方法是类似的
class App extends React.Component {
// ... other codes omitted for brevity
render() {
return (
<UserContext.Provider value = {this.state}>
<Header/>
</UserContext.Provider>
)
}
}