我们都知道在React中,setState() 方法是用来改变组件状态的,在项目中也一直用,也没有出现什么问题(使用方法太简单了),但今天看了一篇文章,提到了setState 使用时的两个注意点,加深了对setState()的认识。

  setState() 最简单的使用方式,就是给它传递一个对象,对象中的属性就是我们要改变的状态,对象中只写我们要改变的那些状态就可以了,react 会把我们这次所做的改变和原来没有做改变的状态进行合并,形成最新的状态,重新渲染组件。写一个简单的例子,点击按钮显示点击的次数,create-react-app 创建项目,在App.js 中写以下内容

import React from "react";

export default class App extends React.Component {

    state = {
counter: 0
}
handleClick = () => {
this.setState({
counter: this.state.counter + 1
})
}
render() {
return (
<div>
<p>点击了{this.state.counter}次</p>
<button onClick={this.handleClick}>点击</button>
</div>
)
}
}

  再简单不过了,但这时,你想增加一个是否点击的状态hasButtonBeenClicked, 只要counter > 0 就算点击了,相当然的,在setState() 方法中,加了

hasButtonBeenClicked 的更改

this.setState({
counter: this.state.counter + 1,
hasButtonBeenClicked: this.state.counter > 0 });

  app.js 更改如下:

export default class App extends React.Component {

    state = {
counter: 0,
hasButtonBeenClicked: false // 点击状态,默认是false
}
handleClick = () => {
this.setState({
counter: this.state.counter + 1,
hasButtonBeenClicked: this.state.counter > 0 // 更改点击状态
});
}
render() {
return (
<div>
<p>是否点击了{this.state.hasButtonBeenClicked.toString()}, 点击了{this.state.counter}次</p>
<button onClick={this.handleClick}>点击</button>
</div>
)
}
}

  你点击按钮一次,发现一个问题,是否点击显示false, 但确显示了点击了1次。

  

  这就是setState()的异步操作,一直知道setState()是异步改变状态,但没有这么写过,当调用setState 改变件的状态的时候,它并不会立即生效,React 为了提高效率,可能选择把几个状态的更改作为一组,一起改状态。也就是setState 中,如果我们更改的第二个或以后的状态,如果依赖第一个状态的改变,它有可能不生效。由于异步操作,第二个或以后的状态,不会取到最新的第一个状态的值。第二行中的hasButtonBeenClicked 中的this.state.counter 并不会获取到第一行中设置的最新状态,它仍然获取到的是this.state.counter 的旧值。

  如果,第二个状态依赖第一个状态,它就要用到setState 的第二个参数,回调函数,只有第一个状态set 成功之后,它才会执行这个回调, setState() 更改如下

handleClick = () => {
this.setState({ counter: this.state.counter + 1 },
() => this.setState({ hasButtonBeenClicked: this.state.counter > 0 }));
}

  第二个注意点,就是重复更改一个值。当使用seState()重复地修改一个状态的值的时候(handleClick的for循环),它并不会把所有的装态值都反应出来,而是取一个最近的值就完事了。

handleClick = () => {
for (let index = 0; index < 5; index++) {
this.setState({ counter: this.state.counter + 1 });
}
}

  当点击按钮的时候,它显示的是1, 而不是5. 每点击一次,只加1. 这时要使用setState的第二种方式,setState的第一个参数,除了对象外,还可以接受一个函数(state, prop) 作为参数,要返回更新状态, 如下,这时你会发现显示5.

handleClick = () => {
for (let index = 0; index < 5; index++) {
this.setState(state => ({
counter: state.counter + 1
}))
}
}

最新文章

  1. 初学JavaScript
  2. 采用cocos2d-x lua 的listview 实现pageview的翻页效果之上下翻页效果
  3. 使用ZooKeeper实现软负载均衡(原理)
  4. AE,按照属性值关系选择要素
  5. 一个链接直接打开APP
  6. “请运行Chkdsk工具”怎么解决
  7. Java--多线程读取网络图片并保存在本地
  8. 使用jQuery为表单添加回车事件
  9. Linux CPU相关信息查看
  10. C语言实现strcmp
  11. URAL1009
  12. tabhost中setup()和setup(LocalActivityManager activityGroup)
  13. C++学习笔记-2-构造函数和析构函数
  14. Oracle 闪回表实验
  15. vagrant up 失败解决办法
  16. Python学习日记:day5-------dict字典
  17. [五] JavaIO之InputStream OutputStream简介 方法列表说明
  18. GlusterFS
  19. [javaEE] Tomcat的安装与配置
  20. C# 反射和Type类

热门文章

  1. Linux下使用cx_Oracle的一些配置
  2. linux cpu信息查看
  3. python 通过scapy获取网卡列表
  4. js语法中一些容易被忽略,但会造成严重后果的细节
  5. NOIP 2004 联合权值
  6. Scrapy笔记02- 完整示例
  7. Scrapy笔记07- 内置服务
  8. Margin和padding失效
  9. js面向对象杂谈
  10. Visual Studio源服务器缓存