博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React之setState
阅读量:5966 次
发布时间:2019-06-19

本文共 1802 字,大约阅读时间需要 6 分钟。

使用过React的用户都知道setState是一个管理state的重要方法,下面简单介绍下这个API。

setState不会立即改变组件中state的值

我们知道,this.state是只读的,更新状态不能直接修改,而是通过this.setState方法。这是为什么呢?this.state只是一个对象,我们修改它的值是没有意义的。仔细想一想,我们之所以要修改state,无非是为了改变页面的渲染状态;所以React设计setState方法就是为了重新渲染页面。

我们可以在setState之后打印一下this.state的值,会发现它并没有改变,还是之前的值。如果我们需要在短时间内多次setState,并且每次setState的值跟之前的状态有关,我们就需要使用函数作为setState的参数了,这个函数参数接收两个参数(当前的state和当前的props)。举个例子:

// 可能最终产生的结果是this.state.value只增加了1function test1() {    this.setState({ value: this.state.value + 1 });    this.setState({ value: this.state.value + 1 });    this.setState({ value: this.state.value + 1 });}// 换种写法,结果就如我们所意了function test2() {    this.setState((state, props) => ({ value: state.value + 1 }));    this.setState((state, props) => ({ value: state.value + 1 }));    this.setState((state, props) => ({ value: state.value + 1 }));}复制代码

因为使用函数式setState,React会保证每次调用函数时,state都已经合并了之前的状态修改结果。

setState还有第二个参数callback,所以下面这种写法也是可以的:

this.setState({ value: this.state.value + 1 }, (val) => {  this.setState({ value: this.state.value + 1 }, () => {    this.setState({ value: this.state.vavlue + 1 });  });});复制代码

我个人还是比较倾向于函数式setState的写法。

貌似有时候setState也会同步更新state,比如使用setTimeout/setInterval或者addEventListener处理事件。具体参考

多次setState会合并

前面我们了解到setState并不会立即改变state的值,而是将其放到一个任务队列里,最终将多个setState合并,一次性更新页面。所以我们可以在代码里多次调用setState,每次只需要关注当前修改的字段即可。

另外,需要注意的是,setState触发页面重新渲染需要经过以下生命周期:

  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

经过测试,其实state的值只有在render的时候才真正被修改了,在shouldComponentUpdate和componentWillUpdate时还是之前的值。测试结果如下:

// shouldComponentUpdate: 0// componentWillUpdate: 0// render: 1// componentDidUpdate: 1// shouldComponentUpdate: 1// componentWillUpdate: 1// render: 2// componentDidUpdate: 2// shouldComponentUpdate: 2// componentWillUpdate: 2// render: 3// componentDidUpdate: 3复制代码

参考:

转载地址:http://pptax.baihongyu.com/

你可能感兴趣的文章
使用dotenv管理环境变量
查看>>
温故js系列(11)-BOM
查看>>
Vuex学习
查看>>
bootstrap - navbar
查看>>
切图崽的自我修养-[ES6] 编程风格规范
查看>>
服务器迁移小记
查看>>
FastDFS存储服务器部署
查看>>
Android — 创建和修改 Fragment 的方法及相关注意事项
查看>>
swift基础之_swift调用OC/OC调用swift
查看>>
Devexpress 15.1.8 Breaking Changes
查看>>
ElasticSearch Client详解
查看>>
mybatis update返回值的意义
查看>>
expdp 详解及实例
查看>>
通过IP判断登录地址
查看>>
深入浅出JavaScript (五) 详解Document.write()方法
查看>>
Beta冲刺——day6
查看>>
在一个程序中调用另一个程序并且传输数据到选择屏幕执行这个程序
查看>>
代码生成工具Database2Sharp中增加视图的代码生成以及主从表界面生成功能
查看>>
关于在VS2005中编写DLL遇到 C4251 警告的解决办法
查看>>
提高信息安全意识对网络勒索病毒说不
查看>>