"useState" 函数中的意外状态更新结果
Unexpected state update results in "useState" function
考虑这个简单的例子,其中一个函数用于更新 useState
对象:
App.tsx
import { useState } from 'react';
export default function App() {
const [state, setState] = useState({
id: 0,
});
const update = () => {
setState(prev => {
const id = Date.now();
console.log('previous id:', prev.id, 'new id:', id);
return {
id,
};
});
};
return (
<div>
<div>state: {JSON.stringify(state)}</div>
<button onClick={update}>Update</button>
</div>
);
}
将其放入标准的 create-react-app typescript 模板(使用 React 17.0.2),然后 运行 应用处于开发模式。继续点击更新按钮,观察控制台。很快就会 运行 进入预期状态和实际状态之间的差异,例如
previous id: 1636301326090 new id: 1636301326260
previous id: 1636301326260 new id: 1636301326440
previous id: 1636301326440 new id: *1636301326611*
previous id: *1636301326612* new id: 1636301326804 // What???
previous id: 1636301326804 new id: 1636301326997
在上面的控制台日志中,id: 1636301326612
状态突然出现,因为设置的状态是 id: 1636301326611
。
仍然很奇怪,当应用程序是为生产而构建时,我无法重现这一点。此外,如果我放弃功能更新并像注释掉的代码一样将对象传递给 setState
(由于原子性要求,在我的实际非玩具代码中不可行),问题似乎也不存在.
我完全不知所措。我是不是用错了setState
?
如有必要,我可以提供完整的示例代码库。
可能是开发中严格模式调用了两次setState所致
设置状态值不依赖于之前的值,而是依赖于时间。这是副作用。
相关链接
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects
https://github.com/facebook/react/issues/12856
考虑这个简单的例子,其中一个函数用于更新 useState
对象:
App.tsx
import { useState } from 'react';
export default function App() {
const [state, setState] = useState({
id: 0,
});
const update = () => {
setState(prev => {
const id = Date.now();
console.log('previous id:', prev.id, 'new id:', id);
return {
id,
};
});
};
return (
<div>
<div>state: {JSON.stringify(state)}</div>
<button onClick={update}>Update</button>
</div>
);
}
将其放入标准的 create-react-app typescript 模板(使用 React 17.0.2),然后 运行 应用处于开发模式。继续点击更新按钮,观察控制台。很快就会 运行 进入预期状态和实际状态之间的差异,例如
previous id: 1636301326090 new id: 1636301326260
previous id: 1636301326260 new id: 1636301326440
previous id: 1636301326440 new id: *1636301326611*
previous id: *1636301326612* new id: 1636301326804 // What???
previous id: 1636301326804 new id: 1636301326997
在上面的控制台日志中,id: 1636301326612
状态突然出现,因为设置的状态是 id: 1636301326611
。
仍然很奇怪,当应用程序是为生产而构建时,我无法重现这一点。此外,如果我放弃功能更新并像注释掉的代码一样将对象传递给 setState
(由于原子性要求,在我的实际非玩具代码中不可行),问题似乎也不存在.
我完全不知所措。我是不是用错了setState
?
如有必要,我可以提供完整的示例代码库。
可能是开发中严格模式调用了两次setState所致
设置状态值不依赖于之前的值,而是依赖于时间。这是副作用。
相关链接
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects
https://github.com/facebook/react/issues/12856