State updater function 在类和函数组件中都是必需的。 this.setState 不应与 this.state 一起使用,同样适用于 useState 状态和状态设置器。 useState 在不使用状态更新器时会导致错误行为的情况更多。
在类组件中,使用this.state 的唯一问题是由于异步状态更新导致的竞争条件:
componentDidMount() {
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 }); // overwrites with stale count
console.log(this.state.count); // not updated
}
当没有竞争条件时,this.state 可以在组件内的任何位置访问,因为 this 引用保持不变:
componentDidMount() {
this.setState({ count: this.state.count + 1 });
setTimeout(() => {
this.setState({ count: this.state.count + 1 });
}, 100)
setTimeout(() => {
console.log(this.state.count);
}, 200)
}
在函数式组件中,使用useState 状态的问题在于函数作用域。没有像这样可以通过引用访问的对象,状态是通过值访问的,在重新渲染组件之前不会更新:
const [count, setCount] = useState(0);
useEffect(() => {
// runs once on mount
// count is always 0 in this function scope
setCount({ count: count + 1 });
setTimeout(() => {
setCount({ count: count + 1 }); // overwrites with stale count
}, 100)
setTimeout(() => {
console.log(count); // not updated
}, 200)
}, []);