setState(…)用于修改Component内部的state,常见有三种写法。
1. 传入新State对象
import React from "react"; import { Button } from "antd"; export default class Test extends React.Component { state = { nummber: 1 } add = () => { for (let i = 0; i < 10; ++i) { this.setState({ number: this.state.nummber + 1 }); console.log(this.state.nummber); } } render = () => { return <Button onClick={event => this.add()}>Add</Button>; } }
输出结果:全是1。
react把短时间内的多次setState合并放入更新队列,然后再批量update component state。引入一个问题:setState后,通过this.state得到的并不一定时setState修改后的状态。
2. 传入新State对象以及回调函数
add = () => { for (let i = 0; i < 10; ++i) { this.setState({ number: this.state.number + 1 }, () => { console.log(this.state.number); }); } }
输出结果:全是2。
回调函数会在setState更新到组件后执行。使用场景:在当前setState生效后,执行回调函数做一些处理。但是上面的问题还没有解决,setState拿到的不是上一个setState修改后的状态。
3. setState传入一个函数
add = () => { for (let i = 0; i < 10; ++i) { this.setState((state) => { console.log(state.number); return { number: state.number + 1 }; }) } }
输出结果:
传入的函数,参数是最新的state,返回值是要修改的state。这种写法,能保证每次拿到的state是最新的。使用场景:本次计算严格依赖于所有setState()执行后的状态,例如antd table的resize column例子,新宽度依赖于前面修改的宽度。
P.S.
setState函数式写法,可以有两个参数。第一个参数为组件的state,第二个参数为组件的props。
this.setState((state, props) => { return { number: 1 }; // new state })