我正在使用React和Context API将userId存储在Context中。
Authenticator 组件位于我的 ContextProvider 下,并将userId存储在上下文中,效果很好。
但是,我想从另一个组件 MySpace 中的上下文中使用此userId,以获取有关当前用户的一些数据。但是在 MySpace 的ComponentDidMount()函数中,this.context.userId为null。我认为这是因为我的ContextProvider正在执行setState()来存储userId,并且在setState()完成之前已安装 MySpace 。
这是我的代码,我不知道是否需要使用其他生命周期方法获取数据。
App.js
class App extends Component {
render() {
return (
<Router history={history}>
<UserContextProvider>
<Authenticator />
<Navbar />
<Switch>
<Route exact path='/' component={Home} />
<Route path='/register' component={Register} />
<Route path='/login' component={Login} />
<PrivateRoute path='/my-space' component={MySpace} />
<Route component={NotFoundPage} />
</Switch>
</UserContextProvider>
</Router>
);
}
}
UserContext.js
export const UserContext = createContext();
class UserContextProvider extends React.Component {
state = {
userId: null
}
replaceUser = (userId) => {
this.setState({ userId: userId });
}
render() {
return (
<UserContext.Provider value={{...this.state, replaceUser: this.replaceUser}}>
{this.props.children}
</UserContext.Provider>
);
}
}
Authenticator.js
class Authenticator extends Component {
static contextType = UserContext;
componentDidMount() {
const { replaceUser } = this.context;
replaceUser(getUserId());
}
render() {
return (
<></>
);
}
}
MySpace.js
class MySpace extends Component {
static contextType = UserContext;
componentDidMount() {
document.title = "Mon espace - Todo";
this.getMyProjects();
}
getMyProjects = () => {
const { userId } = this.context
console.log(userId) // => null
_getMyProjects(userId)
.then(projects => {
console.log(projects)
})
.catch(err => alert(err))
}
render() {
return (
<p>Mon espace</p>
)
}
}
答案 0 :(得分:0)
在我的示例中,当使用 isReady
时,您可能会发现ContextProvider何时使用userId并准备好获取数据,只是需要您所在状态的另一个支持。
export const UserContext = createContext();
class UserContextProvider extends React.Component {
state = {
isReady: false,
userId: null
}
replaceUser = (userId) => {
this.setState({ userId: userId, isReady: true });
}
render() {
return (
<UserContext.Provider value={{...this.state, replaceUser: this.replaceUser}}>
{this.props.children}
</UserContext.Provider>
);
}
}
在byour MySpace组件中,您需要在componentDidUpdate中检查isReady标志是否为true,您可以使用用户ID来获取数据:
class MySpace extends Component {
static contextType = UserContext;
componentDidMount() {
document.title = "Mon espace -
}
componentDidUpdate(){
if(this.context.isReady){
this.getMyProjects();
}
}
getMyProjects = () => {
const { userId } = this.context
console.log(userId) // => null
_getMyProjects(userId)
.then(projects => {
console.log(projects)
})
.catch(err => alert(err))
}
render() {
return (
<p>Mon espace</p>
)
}
}
我认为这可以解决您的问题,该方法可能不是创建新的道具,而只是检查上下文 userId 是否不同于null,因为 null 是您的初始状态