React.useState 以错误的状态重新渲染
React.useState re-renders with wrong state
我有以下简化的代码来控制我的仪表板
function App(props){
const [role, setRole] = React.useState("guest");
const [componentDrawerRender, setComponentDrawerRender] = React.useState(null);
const handleSelectionDrawerClick = (component) => {
setComponentDrawerRender(component);
handleOpenComponentDrawer(true);
};
const handleLoginCallback = (user) => {
if (user !== false) {
handleCloseComponentDrawer();
setRole(user.type); <-- setting the new state does not work
console.log(val.type + " -> " + role ); <-- this here shows != values
} else {
//do nothing
}
};
return (
<Button
onClick={() => {
handleSelectionDrawerClick(
<LoginPage callback={handleLoginCallback} />
);
}}
>
LOG IN
</Button>);
}
此代码的目的是打开一个抽屉(它确实如此),在抽屉中呈现一个组件(它确实如此),并在用户使用该组件登录后关闭抽屉(它确实如此)并更新状态(几乎是这样)。
问题出现在 handleLoginCallback
方法中。发送回好的数据,并用好的数据更新状态。但是,只有页面上的某些组件会更新。
功能组件的重新渲染过程是如何工作的?它只是再次调用该函数还是只是以某种方式重新计算 return 值?以下代码不会在重新渲染时重新计算。让一些状态依赖于其他状态可以吗?
const [mainList, setMainList] = React.useState((role) => {
console.log(role);
if (role === undefined || role === null) {
return GuestListItems(handleSelectionDrawerClick);
} else if (role === "customer") {
return CustomerListItems;
} else {
return OwnerListItems;
}
});
下面是<LoginPage>
中调用回调方法的代码。
onSubmit(e) {
e.preventDefault();
this.setState({ isLoading: true });
this.props.login(this.state, this.handleLoadingBar).then((retState) => {
if(retState === null){
this.props.callback(false); <-- here
}else {
this.props.callback(retState); <-- here
}
});
}
在您的代码中,role
值在后续刷新(即函数调用)时更新,因为 setRole
调用。有几个原因导致 console.log
行的角色没有改变:
role
被标记为常量;
- JavaScript 在当前函数完成之前不会 运行 任何其他函数(更好:调用堆栈变空)。
也检查一下:https://reactjs.org/docs/hooks-reference.html#functional-updates
useState
钩子是一个普通函数,它获取一个参数,returns 一个元组。尽管每次刷新都会调用挂钩(以及参数),但参数值仅在第一次初始化时使用。
这里是 API 描述:https://reactjs.org/docs/hooks-reference.html#usestate
onSubmit(e) {
e.preventDefault();
this.setState({ isLoading: true });
this.props.login(this.state, this.handleLoadingBar).then((retState) => {
if(retState === null){
this.props.callback(false); <-- here
}else {
this.props.callback(retState); <-- here
}
});
}
您正在将 this 的初始状态设置为函数 no 到函数的结果。
我有以下简化的代码来控制我的仪表板
function App(props){
const [role, setRole] = React.useState("guest");
const [componentDrawerRender, setComponentDrawerRender] = React.useState(null);
const handleSelectionDrawerClick = (component) => {
setComponentDrawerRender(component);
handleOpenComponentDrawer(true);
};
const handleLoginCallback = (user) => {
if (user !== false) {
handleCloseComponentDrawer();
setRole(user.type); <-- setting the new state does not work
console.log(val.type + " -> " + role ); <-- this here shows != values
} else {
//do nothing
}
};
return (
<Button
onClick={() => {
handleSelectionDrawerClick(
<LoginPage callback={handleLoginCallback} />
);
}}
>
LOG IN
</Button>);
}
此代码的目的是打开一个抽屉(它确实如此),在抽屉中呈现一个组件(它确实如此),并在用户使用该组件登录后关闭抽屉(它确实如此)并更新状态(几乎是这样)。
问题出现在 handleLoginCallback
方法中。发送回好的数据,并用好的数据更新状态。但是,只有页面上的某些组件会更新。
功能组件的重新渲染过程是如何工作的?它只是再次调用该函数还是只是以某种方式重新计算 return 值?以下代码不会在重新渲染时重新计算。让一些状态依赖于其他状态可以吗?
const [mainList, setMainList] = React.useState((role) => {
console.log(role);
if (role === undefined || role === null) {
return GuestListItems(handleSelectionDrawerClick);
} else if (role === "customer") {
return CustomerListItems;
} else {
return OwnerListItems;
}
});
下面是<LoginPage>
中调用回调方法的代码。
onSubmit(e) {
e.preventDefault();
this.setState({ isLoading: true });
this.props.login(this.state, this.handleLoadingBar).then((retState) => {
if(retState === null){
this.props.callback(false); <-- here
}else {
this.props.callback(retState); <-- here
}
});
}
在您的代码中,role
值在后续刷新(即函数调用)时更新,因为 setRole
调用。有几个原因导致 console.log
行的角色没有改变:
role
被标记为常量;- JavaScript 在当前函数完成之前不会 运行 任何其他函数(更好:调用堆栈变空)。
也检查一下:https://reactjs.org/docs/hooks-reference.html#functional-updates
useState
钩子是一个普通函数,它获取一个参数,returns 一个元组。尽管每次刷新都会调用挂钩(以及参数),但参数值仅在第一次初始化时使用。
这里是 API 描述:https://reactjs.org/docs/hooks-reference.html#usestate
onSubmit(e) {
e.preventDefault();
this.setState({ isLoading: true });
this.props.login(this.state, this.handleLoadingBar).then((retState) => {
if(retState === null){
this.props.callback(false); <-- here
}else {
this.props.callback(retState); <-- here
}
});
}
您正在将 this 的初始状态设置为函数 no 到函数的结果。