React的setState学习及应用

一:作用:

setState() 将对组件 state 的更改排入队列,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。这是用于更新用户界面以响应事件处理器和处理服务器数据的主要方式。

二: 特性

1、为了更好的感知性能,React 会延迟调用它,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效。批量推迟更新:setState() 是异步的,并且在同一周期内会对多个 setState 进行批处理,后调用的 setState() 将覆盖同一周期内先调用 setState 的值。

import React, {Component} from 'react';

export default class Test extends Component {
constructor(props) {
super(props);
this.state = {
a: 0,
b: 0,
}
} componentDidMount() {
} onClick = () => {
this.setState({
a: this.state.a + 1
})
this.setState({
a: this.state.a + 1
})
this.setState({
b: this.state.b + 1
})
} render() {
console.log('重新渲染', `a=${this.state.a}`, `b=${this.state.b}`);
return (
<div onClick={this.onClick}>按钮</div>
)
} }

打印结果为:

2: 在调用 setState() 后立即读取 this.state,请使用 componentDidUpdate 或者 setState 的回调函数(setState(updater, callback)),这两种方式都可以保证在应用更新后触发。

使用updater函数 (updater 函数中接收的 state 和 props 都保证为最新):

onClick = () => {
this.setState((state, props) => {
return {
a: state.a + 1,
b: state.b + 1,
}
}) this.setState((state, props) => {
return {
a: state.a + 1,
b: state.b + 1,
}
})
}

打印结果为:

这里并没有打印两次,说明updater函数也是批量推迟更新。

使用回调函数: setState() 的第二个参数为可选的回调函数,它将在 setState 完成合并并重新渲染组件后执行。通常,我们建议使用 componentDidUpdate() 来代替此方式。

onClick = () => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
}, () => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
})
}

打印结果为:

使用componentDidUpdate()。此生命周期和render()一样,都不能在内部使用setstate方法,不然会导致死循环,只能读,不能改。

componentDidUpdate() {
console.log('重新渲染结束', `a=${this.state.a}`, `b=${this.state.b}`);
} onClick = () => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
}

打印结果为:

三:setstate是异步还是同步?

有时表现出异步,有时表现出同步

1、setState只在合成事件和钩子函数中是“异步”的,在原生事件和setTimeout 中都是同步的。

2、setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。

3、setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新。

settimeout

onClick = () => {
setTimeout(() => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
})
}

打印结果为:

原生事件:

componentDidMount() {
const btn = document.getElementById('btn');
btn.addEventListener('click', this.onDomClick, false)
} onDomClick = () => {
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
this.setState({
a: this.state.a + 1,
b: this.state.b + 1,
})
} render() {
console.log('重新渲染', `a=${this.state.a}`, `b=${this.state.b}`);
return (
<div id='btn'>按钮</div>
)
}

打印结果为:

最新文章

  1. 4. UIButton的使用
  2. ANDROID学习书单
  3. smartmontools的安装使用和实现对磁盘的Nagios监控
  4. Laravel 5 基础(十二)- 认证
  5. HTTP中缓存相关
  6. APP,webapp 设计相关资料汇集区
  7. python高级编程:有用的设计模式2
  8. springmvc-interceptor(拦截器)
  9. MD5的Hash长度扩展攻击
  10. 【珍藏】linux 同步IO: sync、fsync与fdatasync
  11. [bzoj1692] [Usaco2007 Dec]队列变换 (hash||暴力)
  12. mysql 学习心得2
  13. 【Java】身份证号码验证
  14. 实现两个sym转一个sym
  15. AngularJS入门基础——表单验证
  16. 图片水平垂直居中(兼容IE6,IE7,firefox,opera,safari,其中图片可以是任何块元素)
  17. 在php代码中调用帝国cms头部变量temp.header的方法
  18. 排查 Azure 虚拟机的远程桌面连接问题
  19. git 本地与远程分支冲突 解决
  20. NFA/DFA算法

热门文章

  1. NFS介绍、服务端安装配置、NFS配置选项
  2. block中self会造成循环引用问题
  3. js杂项积累
  4. 服务器RAID技术基础
  5. IO到NIO的一个转变
  6. Apache服务——个人用户主页功能
  7. mac eclipse maven tomcat 运行错误 tomcat HTTP Status 404
  8. 《JavaScript 正则表达式迷你书》知识点小抄本
  9. 小胖求学系列之-文档生成利器(上)-smart-doc
  10. HashMap面试必问的6个点,你知道几个?