此文主要探讨了 React JS 中的 setState 背后的机制,供深入学习 React 研究之用。
在课程 React.js入门基础与案例开发 中,有些同学会发现 React JS 中的 setState 的表现好像有点怪异,和理解中的 state 更新机制不太一样,下面我们就来简单探讨下 setState 背后的机制。
课程中的其他常见小问题请常见 React.js 开发参见问题 Q&A。
1 setState 问题的复现
我们看下面一段简单的代码,代码通过点击一个按钮,改变 state 中的 clicked 值。在修改值后进行 clicked 值的输出,你尝试猜测一下输出的值是什么?
许多同学在自己写代码遇到类似逻辑的时候都会发现,console.log(this.state.clicked);
这段代码输出的不是我们预期的 true,而是 false。
这是为什么呢?
2 setState 的内部机制
遇到问题我们还是去官方文档找线索。
我们看到 state 的章节有下面这段话。
文章链接在这里:https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous。
我们会发现其实 React 的 setState 方法是一个异步的方法,React 会将所有的 setState 方法打包成一次进行更新,类似于快递点寄快递,囤积了一些包裹后一次投递,而不是你每次修改 state 都会进行更新。
这样的设计主要是为了提高 UI 更新的性能,我们知道 React 中 state 的改变会导致 UI 的更新。
如果需要进行同步操作逻辑,那么在回调函数里添加逻辑即可。
{% codeblock lang:js%}
handleClick = () => {
this.setState({
clicked: true
}, () => console.log(this.state.clicked)) //这时候输出的是 true
}
{% endcodeblock %}
3 state 的更新时机
任何 state 的更新都会导致 React 进行重新渲染。props
也会导致 React 进行重新渲染。组件与父组件的更改同样也会引起 React 的重新渲染。
那么我们有没有办法手动控制 React 是否进行渲染呢?
这里,你应该想起来生命周期函数里有一个方法 shouldComponentUpdate
。
shouldComponentUpdate 方法官方文档。
此方法默认每次在需要进行重新渲染时返回 true,但是在这个函数里你可以添加自己的逻辑,控制 React 不进行渲染以及渲染的条件。
那么,同样,我们也可以在此函数中定义那些我们关注的 state ,只有当它们变化才让 React 进行重新渲染,而其他一些不相关的 state 的值即使变化了,我们也可以让 React 不进行渲染。
理解了这些,那么在你进行相关性能优化时就非常有用。
深入理解 React JS 中的 setState的更多相关文章
-
从源码的角度再看 React JS 中的 setState
在这一篇文章中,我们从源码的角度再次理解下 setState 的更新机制,供深入研究学习之用. 在上一篇手记「深入理解 React JS 中的 setState」中,我们简单地理解了 React 中 ...
-
从源码的角度看 React JS 中批量更新 State 的策略(下)
这篇文章我们继续从源码的角度学习 React JS 中的批量更新 State 的策略,供我们继续深入学习研究 React 之用. 前置文章列表 深入理解 React JS 中的 setState 从源 ...
-
从源码的角度看 React JS 中批量更新 State 的策略(上)
在之前的文章「深入理解 React JS 中的 setState」与 「从源码的角度再看 React JS 中的 setState」 中,我们分别看到了 React JS 中 setState 的异步 ...
-
深入理解Node.js中的垃圾回收和内存泄漏的捕获
深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...
-
深入理解three.js中光源
前言: Three.js 是一个封装了 WebGL 接口的非常好的库,简化了 WebGL 很多细节,降低了学习成本,是当前前端开发者完成3D绘图的得力工具,那么今天我就给大家详细讲解下 Three.j ...
-
深入理解Three.js中透视投影照相机PerspectiveCamera
前言 在开始正式讲解透视摄像机前,我们先来理理three.js建模的流程.我们在开始创建一个模型的时候,首先需要创建我们模型需要的物体,这个物体可以是three.js中已经为我们封装好的,比如正方体, ...
-
深入理解Three.js中正交摄像机OrthographicCamera
前言 在深入理解Three.js中透视投影照相机PerspectiveCamera那篇文章中讲解了透视投影摄像机的工作原理以及对应一些参数的解答,那篇文章中也说了会单独讲解Three.js中另一种常用 ...
-
深入理解Three.js中线条Line,LinLoop,LineSegments
前言 在可视化开发中,无论是2d(canvas)开发还是3d开发,线条的绘制应用都是比较普遍的.比如绘制城市之间的迁徙图,运行轨迹图等.本文主要讲解的是Three.js中三种线条Line,LineLo ...
-
React.js 小书 Lesson21 - ref 和 React.js 中的 DOM 操作
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson21 转载请注明出处,保留原文链接和作者信息. 在 React.js 当中你基本不需要和 DO ...
随机推荐
-
Windows Phone 十二、设计器同步
在设计阶段为页面添加数据源 Blend或者VS的可视化设计器会跑我们的代码,然后来显示出来,当我们Build之后,设计器会进入页面的构造函数,调用InitializeComponent();方法来将U ...
-
linux 学习5 文本编辑器 vim
vim 没有菜单,只有命令 //root用户既可以用vi,也可以用vim, 无实质性区别,vim是vi的升级版//粘贴用shift+insert , 要在insert模式下粘贴,否则粘贴不全// ^ ...
-
C# 根据类名称创建类示例
//获得类所在的程序集名称(此处我选择当前程序集) string bllName = System.IO.Path.GetFileNameWithoutExtension(System.Reflect ...
-
facebook graphql
思想先进,前端直接从后台调用所需要的数据. 最简单的理解: 从"select * from 学生表" 进化为"select name, sex from 学生表" ...
-
1. Netty解决Tcp粘包拆包
一. TCP粘包问题 实际发送的消息, 可能会被TCP拆分成很多数据包发送, 也可能把很多消息组合成一个数据包发送 粘包拆包发生的原因 (1) 应用程序一次写的字节大小超过socket发送缓冲区大小 ...
-
转载:T-SQL语句大全
一.基础 1.创建数据库 CREATE DATABASE database-name 2.删除数据库 drop database dbname 3.备份数据库 --- 创建 备份数据的 device ...
-
自定义UITableViewCell时, 使用autoLayout, 无法很好的做到屏幕适配
解决方法: 重写cell的setFrame方法即可 - (void)setFrame:(CGRect)frame { frame.size.width = self.window.frame.size ...
-
C/C++修改常量的值
C/C++中常量修饰const可以用来保证一些确定的量不会被一不小心改变,比如PI,一直是3.14159...... 但是不排除有时候也会需要修改常量的值,通过直接修改是不能达到目的. 比如: #in ...
-
zf-关于统计分析表单导出(写这个的 太麻烦了)
一个类里面写了2个一样的方法 如果是我 会重复利用 而不是这样写 今天改bug的时候我把一个类修改了2次 差点以为进错了类
-
制作Docker镜像
编写DockerFile 这个DockerFile是一个制作镜像的配方,用于描述这些文件,环境,和命令.在Linux.macOS的窗口终端中,或者windows的命令提示符下,执行下面的步骤,切记如果 ...