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 ...
随机推荐
- Apache Kyuubi 助力 CDH 解锁 Spark SQL
Apache Kyuubi(Incubating)(下文简称Kyuubi)是⼀个构建在Spark SQL之上的企业级JDBC网关,兼容HiveServer2通信协议,提供高可用.多租户能力.Kyuub ...
- 分析师机构发布中国低代码平台现状分析报告,华为云AppCube为数字化转型加码
摘要:Forrester指出,中国企业数字化转型过程中,有58%的决策者正在采用低代码工具进行软件构建,另有16%的决策者计划采用低代码. 华为消息,知名研究与分析机构Forrester Resear ...
- [bzoj1188]分裂游戏
容易发现所有豆子相互独立,只需要考虑每一个豆子的sg函数并异或起来即可,sg函数从后往前暴力即可 1 #include<bits/stdc++.h> 2 using namespace s ...
- [loj3346]交换城市
观察可得,$(x,y)$能相互到达当且仅当:1.$x$和$y$联通:2.$x$和$y$所在的连通块不为链 根据这个结论,可以二分枚举答案+暴力判定,复杂度$o(qm\log_{2}1e9)$,可以通过 ...
- idea 的git代码回退回某个版本
intellij idea 的git代码回退回滚 找到Reset HEAD 填写提交码,注意这里要选择"hard" 使用命令行强制提交代码 git push -f
- Python画一个四点连线并计算首尾距离
import turtle import math #先定义4个坐标 x1,y1=100,100 x2,y2=100,-100 x3,y3=-100,-100 x4,y4=-100,100 #然后 ...
- [ARC 122]
最近状态差到爆炸. \(AT\)连掉两把分,啥时候能上黄啊. \(A\) 考虑直接动归. 把\(O(n^2)\)的动归后缀和优化成\(O(n)\) A #include<iostream> ...
- CF605E Intergalaxy Trips
CF605E Intergalaxy Trips 考虑你是不知道后来的边的出现情况的,所以可以这样做:每天你都选择一些点进行观察,知道某天往这些点里面的某条边可用了,你就往这条边走.这样贪心总是对的. ...
- Mysql 预处理 PREPARE以及预处理的好处
Mysql 预处理 PREPARE以及预处理的好处 Mysql手册 预处理记载: 预制语句的SQL语法在以下情况下使用: · 在编代码前,您想要测试预制语句在您的应用程序中运行得如何.或者也许一个 ...
- 搭建简单的SpringCloud项目二:服务层和消费层
GitHub:https://github.com/ownzyuan/test-cloud 前篇:搭建简单的SpringCloud项目一:注册中心和公共层 后篇:搭建简单的SpringCloud项目三 ...