从这节课开始,我们给大家扩展几项内容,这节课扩展第一块,setState

setState更新状态的两种写法

我们之前更新state是不是都直接通过setState然后传一个对象进去?但是实际上呢还有另外一种写法来完成setState

我们先来实现一个案例:

import React, { Component } from 'react';

export default class SetState extends Component {
  state = { sum: 0 }
  render() {
    return (
      <div>
        <h2>sum is : {this.state.sum}</h2>
        <button onClick={this.handleClick}>click</button>
      </div>
    );
  }
  handleClick = () => {
    const { sum } = this.state
    this.setState({ sum: sum + 1 })
  }
}

我们来看这段代码,我们是不是实现了一个点击按钮就使得数字加一的操作?

再来看我们的setState方法,里面传的就是一个对象,里面写了我们要修改的属性以及属性的值。那么我们来看一下效果:

iShot2022-01-20 13.27.16

我们看一下可以实现我们的需求,这就是我们的第一种写法。

但是呢实际上setState的第一种写法其实是包含两个参数的:

  • stateChange,这就是我们要修改的数据的对象
  • callback,这是一个回调函数,会在修改了state并且完成了render的调用之后执行,但是这个参数可以不传

为什么要有这个参数呢?因为setState是一个异步任务,比如我们看下面这段:

export default class SetState extends Component {
  state = { sum: 0 }
  render() {...}
  handleClick = () => {
    const { sum } = this.state;
    this.setState({ sum: sum + 1 });
    console.log(this.state.sum);
  }
}

我们来看这段代码,这是干什么?我们在第六行是不是改了状态?但是我想在第 7 行来看一下我们改之后的状态,那么我们来看一下结果:

image-20220120133435532

输出是 0,这不对啊,我们已经修改了状态了啊,按理说这里应该是 1 才对啊,这就是因为setState是异步任务,他在收到消息之后去后台悄悄去改状态取了,但是与此同时呈现并没有等他把状态改完,而是在setState要去开始改状态的时候,然后就已经开始执行下面的代码了。

那么这个时候setStatecallback参数的作用就出来了,我们来看一下:

export default class SetState extends Component {
  state = { sum: 0 }
  render() {...}
  handleClick = () => {
    const { sum } = this.state;
    this.setState({ sum: sum + 1 }, ()=>console.log(this.state.sum));
  }
}

这是什么意思?我们是不是穿了个函数给steState?那么这个函数会在什么时候调用?页面更新之后调用,那么我们再来看一下结果:

image-20220120133949088

这一次我们的结果就没有问题了。那么我们再来看第二种写法,和第一种写法很相似,也接两个参数,其中一个也是callback,也是在页面更新之后再调callback,而且也可以不传。但是有一点不同,就是第二种写法的第一个参数要传一个函数,这个函数可以接收stateprops。比如我们在App中传一个 x=10

export default class SetState extends Component {
  state = { sum: 0 }
  render() {...}
  handleClick = () => {
    this.setState((state, props) => ({ sum: state.sum + props.x }));
  }
}

我们来看一下这段代码,什么意思?我们是不是直接接收到stateprops,我们现在每点一次按钮是不是就会让state加上我们props传进来的值啊?那么我们看一下效果:

iShot2022-01-20 13.50.31

这样我们就完成了我们的setState的第二种写法。当然了,callback参数和第一种方法一样,我们就不多赘述了。

总结

  • 第一种写法叫对象式setState
  • 第二种写法叫函数式setState
  • 对象式setState是函数式setState的一种简写方式
  • 如果修改状态要依赖原状态则使用函数式
  • 如果修改状态后要马上获取新状态,则传入callback

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/extend_set_state/