使用 React Context 时如何更新状态?
2020-02-10
701
我使用 React Context 传递状态并像这样设置状态
const [authContext, setAuthData] = useState({
isAuthenticated: false,
userID:"-1",
email:"test",
name:"test"
});
<AuthContext.Provider value={[authContext,setAuthData]}>
<Router>
<NavbarMenu />
<div className="AllElements">
<Switch>
<Route exact path="/" component={HomePage} />
<Route component={Routes} />
</Switch>
</div>
</Router>
</AuthContext.Provider>
在另一个组件中,我像这样检索它
const [authContext, setAuthData ] = useContext(AuthContext);
const { isAuthenticated } = authContext;
每当我想要更新 authContext 时,我都会像这样调用 setAuthData
const HomePage = () => {
if(data && data.login && data.login.token){
console.log("Data token exists");
setAuthData(() => [{
isAuthenticated: true,
userID:data.login.id,
email:data.login.email,
name:data.login.name
}]);
}
return (<div><p>test</p></div>);
};
export default HomePage;
但是,一旦它命中 setAuthData,if {} 中的所有内容都会被多次调用。我不断在控制台中看到多个“数据令牌存在”,直到它错误地显示“超出最大更新深度”
3个回答
由于 setAuthData 调用会更改 authContext,因此会出现无限循环。当 authContext 更改时,HomePage 将重新呈现并再次触发 setAuthData。
请确保只调用 setAuthData 一次,例如:
const HomePage = () => {
React.useEffect(() => {
if (data && data.login && data.login.token) {
console.log("Data token exists");
setAuthData(() => [
{
isAuthenticated: true,
userID: data.login.id,
email: data.login.email,
name: data.login.name
}
]);
}
}, [data]);
return (<div><p>test</p></div>);
};
Peter Ambruzs
2020-02-10
我猜你应该在
useEffect
钩子中进行状态更新,并传递第二个参数以便仅在更新时做出反应:
const HomePage = () => {
useEffect(()=>{
//if(data && data.login && data.login.token){
console.log("Data token exists");
setAuthData(() => [{
isAuthenticated: true,
userID:data.login.id,
email:data.login.email,
name:data.login.name
}]);
// }
}, [data]); //<-----second param if it has any changes then run effect
return (<div><p>test</p></div>);
};
Jai
2020-02-10
这可能是问题所在:
const HomePage = () => {
if(data && data.login && data.login.token){
console.log("Data token exists");
setAuthData(() => [{
isAuthenticated: true,
userID:data.login.id,
email:data.login.email,
name:data.login.name
}]);
}
return (<div><p>test</p></div>);
};
export default HomePage;
更新后的状态应该是一个对象,而不是基于父组件中先前状态的数组,因此将返回值更改为:
const HomePage = () => {
if(data && data.login && data.login.token){
console.log("Data token exists");
setAuthData(() => ({
isAuthenticated: true,
userID:data.login.id,
email:data.login.email,
name:data.login.name
}));
}
return (<div><p>test</p></div>);
};
export default HomePage;
正如 peter 的回答中所述,您还应该使用
useEffect
钩子来停止更新周期。
Ramesh Reddy
2020-02-10