react原理分析--this.state修改引起的重新渲染
整理向,非原创,目的是整理出浅显易懂的方向性说明.
比如现有
this.state={name:"小明",age:18}
我们说修改组件的状态要用this.setState()来实现.这里有两个问题
1.为什么?我直接用this.state.age=17能不能实现重新渲染?
不能.因为它只是改变了这个组件当前的状态,并没有调用render().
2.this.setState()的原理是什么?
react中有一个原则:有变化,就一定返回一个新对象;没变化,原对象不做变化直接返回;
结合这个原则我们来分析一下原理:
参数:
this.setState()有三个参数:分别是this.state、nextState和callback.
其中,第一个参数是默认已经给的,为什么还要提出来是为了方便理解.
第二个参数是新状态,也就是我们期望组件能达到的状态.有多种方式.传一个对象或者传一个返回对象的函数.最终效果就是传一个对象.
this.setState({age:17})
第三个参数是设置成功之后的回调函数.
返回值:
this.setState()的返回值是一个新的对象,也就是说是一个新的状态.它使用了Object.assign(),将已修改的属性添加进去.而不是覆盖.
this.state里面有两个属性,如果我 this.setState({age:17}) 这么操作会不会导致this.state里面没有了"name"属性?
不会!我们上面刚说,this.setState()是返回一个新的对象,它会把有变动的改变成变动后的值,没有变动的保留.所以,你完全可以用这个方法去改变其中的某一个值.
接下来我们重点分析内部的原理:
首先,需要根据原来的this.state和传进来的参数来判断是否批量更改(是否批量差了一个收集待改组件的步骤),而这里的this.state是我之前说的默认传进来的.
然后,再根据this.state来计算nextstate. (shouldComponentUpdate()根据拿到的nextstate来返回一个布尔值,true则进行下一步,false,则下一步不执行.然后就进入componentWillUpdate)
接着render()出一个next组件,
最后根据diff算法进行更新渲染. 结束后进入生命周期函数componentDidUpdate()
这里也有几个问题:
(1)假如我调用this.setState()设置的值跟之前一样的,会不会重新渲染一次?
会!因为shouldComponentUpdate()默认肯定返回true,所以一定会往下执行.那为什么我要是根据nextstate返回一个布尔值呢?因为我们可以手动通过这种方式来控制render()来减少无用功,这是shouldComponentUpdate()的功能,只不过没有默认执行而已.
(2)假如我进行多次this.setState()的操作,而且都是同一个属性修改最终以哪次为主?
function stateChange() {
this.setState({age: this.state.age + 1});
this.setState({age: this.state.age + 1});
this.setState({age: this.state.age + 1});
}
这里情况比较复杂,大体上可以理解为在react的体制内setState()是异步操作,所以最后this.state.age最终还是只加了1,比如onClick()这种react原生的事件中.但是体制外的是同步操作.最终会加3.
(3)为啥console.log()拿不到最新的this.state?
如第(2)点所说,setState()是异步操作.还记得上面所说this.setState()还有一个参数是回调函数吗?所以需要在this.setState()的参数里面再传一个回调函数,在函数中打印就能得到this.state.
react原理分析--this.state修改引起的重新渲染的更多相关文章
- React react-redux props或state更新视图无法重新渲染问题
记录学习React时自己是如何挖坑把自己埋了的过程:children以及其它props被修改时相关组件无法重新渲染(做了两天) 父组件代码: class UserHome extends Compon ...
- android黑科技系列——修改锁屏密码和恶意锁机样本原理分析
一.Android中加密算法 上一篇文章已经介绍了Android中系统锁屏密码算法原理,这里在来总结说一下: 第一种:输入密码算法 将输入的明文密码+设备的salt值,然后操作MD5和SHA1之后在转 ...
- 为React绑定事件,并修改state中的值
import React from 'react' export default class ClickS extends React.Component { constructor () { sup ...
- 转载:AbstractQueuedSynchronizer的介绍和原理分析
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析[转]
前面在介绍Android系统的开机画面时提到,Android设备的显示屏被抽象为一个帧缓冲区,而Android系统中的SurfaceFlinger服务就是通过向这个帧缓冲区写入内容来绘制应用程序的用户 ...
- AbstractQueuedSynchronizer的介绍和原理分析(转)
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- 消息队列NetMQ 原理分析4-Socket、Session、Option和Pipe
消息队列NetMQ 原理分析4-Socket.Session.Option和Pipe 前言 介绍 目的 Socket 接口实现 内部结构 Session Option Pipe YPipe Msg Y ...
- Redis事务原理分析
Redis事务原理分析 基本应用 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD ...
- java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析
java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...
随机推荐
- 前端:WebP自适应实践
WebP介绍 WebP 是 Google 推出的一种同时提供了有损和无损两种压缩方式的图片格式,优势体现在其优秀的图像压缩算法,能够带来更小的图片体积,同时拥有更高的的图像质量.根据官方说明,WebP ...
- Electron跨平台程序破解
1. npm install asar -g 2. asar --version 如果有版本号就继续 3.找到需要解压的软件位置 在app.asar的地址输入 asar e app.asar tm ...
- .NET Core基础篇之:依赖注入DependencyInjection
依赖注入已经不是什么新鲜话题了,在.NET Framework时期就已经出现了各种依赖注入框架,比如:autofac.unity等.只是在.net core微软将它搬上了台面,不用再依赖第三方组件(那 ...
- 决策单调性&wqs二分
其实是一个还算 trivial 的知识点吧--早在 2019 年我就接触过了,然鹅当时由于没认真学并没有把自己学懂,故今复学之( 1. 决策单调性 引入:在求解 DP 问题的过程中我们常常遇到这样的问 ...
- 洛谷 P4646 - [IOI2007] flood 洪水(拆点+bfs)
题面传送门 一道挺有意思的题(?) orz djq yyds %%%%%%%%%%%%%%%%%% 首先一个很直观的想法是将每个房间看作一个节点,在有墙的房间旁边连边权为 \(1\) 的边然后 bfs ...
- O(1)判断两点之间是否有边
O(1)判断两点之间是否有边 问题描述 给定一张 \(n\) 个点,\(m\) 条边的有向图. 多次询问,要求每次 \(\mathcal{O}(1)\) 判断两点之间是否有边(你可以忽略输入.输出等问 ...
- Oracle--计算某一日期为一年中的第几周
我自己实现的脚本: select T31267.CREATED_DATE as F31265, (select to_char(to_date(T31267.CREATED_DATE,'yyyy-mm ...
- chown & chmod用法
chown & chmod 1. chown更改文件的属主&属组 NAME chown - 改变文件的属主和属组(change file owner and group) 用法 cho ...
- hadoop基础题
转自:http://blog.csdn.net/pelick/article/details/8299482 //Hadoop基础 Doug Cutting所创立的项目的名称都受到其家人的启发,以下项 ...
- (转载)java中判断字符串是否为数字的方法的几种方法
java中判断字符串是否为数字的方法: 1.用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = 0; i < ...