深入理解 React JS 中的 setState

此文主要探讨了 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 ...
随机推荐
- 使用Bitbucket Pipeline进行.Net Core项目的自动构建、测试和部署
1. 引言 首先,Bitbucket提供支持Mercurial和Git版本控制系统的网络托管服务.简单来说,它类似于GitHub,不同之处在于它支持个人免费创建私有项目仓库.除此之外,Bitbucke ...
- ERROR: unable to bind listening socket for address ’127
ERROR: unable to bind listening socket for address '127.0.0.1:9000′ 解决办法: killall php-fpm 然后重启即可. 我的 ...
- python3 中encode 和decode的使用方法。
编码: 将文本转换成字节流的过程.即Unicode----------->特定格式的编码方式,产生特定的字节流保存在硬盘中(一般为utf-8格式). 解码: 将硬盘中的字节流转换成文本的过程.即 ...
- FastDFS教程IV-文件服务器集群搭建
1.简介 本文主要介绍FastDFS文件服务器的集群搭建,在阅读本文之前,您需具备FastDFS文件服务器单节点安装,扩容,迁移等方面的知识.同时,您还需了解Keepalived,nginx方 ...
- C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.
C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式. 目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形 ...
- Js 作用域与作用域链与执行上下文不得不说的故事 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄
最近在研究Js,发现自己对作用域,作用域链,活动对象这几个概念,理解得不是很清楚,所以拜读了@田小计划大神的博客与其他文章,受益匪浅,写这篇随笔算是自己的读书笔记吧~. 作用域 首先明确一个概念,js ...
- 运行期以索引获取tuple元素-C++17
//运行期以索引获取tuple元素-C++17 //需支持C++17及以上标准的编译器,VS2017 15.5.x.CodeBlocks 16.01 gcc 7.2 //参见:http://purec ...
- 【c语言】实现一个函数,求字符串的长度,不同意创建第三方变量
// 实现一个函数,求字符串的长度.不同意创建第三方变量. #include <stdio.h> #include <assert.h> int my_strlen_no(ch ...
- Winform开发框架中工作流模块之审批会签操作(2)
前面随笔介绍了请假申请单和报销申请单两个不同的业务表单的流程处理,一个是单表信息,一个包含明细的主从表信息,后者包含了条件流程的处理,在流程审批中,一般还有一种流程处理就是会签的操作,会签处理是几个审 ...
- css盒子模型(3)
盒子模型 版权声明 本文原创作者:雨点的名字 作者博客地址:https://home.cnblogs.com/u/qdhxhz/ 在讲理论之前,我们先要知道网页设计中常听的属性名:内容(co ...