reactjs - React 不呈现最新状态
问题描述
我有以下问题。
function App() {
const [state, setState] = useState({ a: 0 });
const handleClick = () => {
Promise.resolve().then(() => {
const _state = { a: 1 };
console.log("1");
setState(_state);
console.log("2");
_state.a = 2;
setState(_state);
console.log("3");
_state.a = 3;
setState(_state);
});
};
return (
<div>
<button onClick={handleClick}>Test</button>
<br />
{console.log("render", state)}
{state.a}
</div>
);
}
单击按钮后,控制台中会显示以下输出:
1
render {a: 1}
2
render {a: 2}
3
但它呈现{a: 1}
而不是{a: 2}
所以最终状态发生了变化,它的值是{a: 3}
,但是 react 没有呈现新值。在 react devtools 中我可以清楚地看到state: {a: 3}
。如果我删除Promise.resolve
代码将按预期工作。
另一个问题是,为什么它会在代码中间调用渲染(在console.log(1)
?
解决方案
在 Promise 回调中,您只在第一次设置状态一次setState(_state);
,在每隔一次尝试时,组件不会渲染,因为 React 渲染工作时,它与之前的状态进行浅比较,这总是正确的,因为它拥有相同的对象参考(它是javascript):
const state = { a: 1};
setState(state); // prevState = state;
state.a = 2;
prevState === state // always true so not render is triggered
这是一个常见的初学者错误,React 声明将状态视为不可变。.
推荐阅读
- php - 在后台模式下运行 bash 脚本时的编码问题
- json - 通过 Snowflake 中的目标表替代 JSON 展平
- c# - Access 数据库应用程序可以跨桌面共享吗?
- javascript - 使用 ElementRef 查询列表在悬停时显示 div
- xml - 由两种模式验证的 XML 文件
- android - 在Android中找不到资产的路径
- r - R Studio - 包 googlesheets 不再起作用
- jekyll - 有没有一种简单的方法可以让 Jekyll 输出文件到 docs/ 目录?
- android - 如何正确监听 FirebaseDatabase 中的子更改
- php - 在 Laravel 6.5 中手动添加旧的东西