React setState方法

By | 6月 18, 2020

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。

image

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。

image

回调函数会在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 };
    })
  }
}

输出结果:

image

传入的函数,参数是最新的state,返回值是要修改的state。这种写法,能保证每次拿到的state是最新的。使用场景:本次计算严格依赖于所有setState()执行后的状态,例如antd table的resize column例子,新宽度依赖于前面修改的宽度。

P.S.

setState函数式写法,可以有两个参数。第一个参数为组件的state,第二个参数为组件的props。

this.setState((state, props) => {
  return { number: 1 }; // new state
})