整理向,非原创,目的是整理出浅显易懂的方向性说明.

比如现有

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修改引起的重新渲染的更多相关文章

  1. React react-redux props或state更新视图无法重新渲染问题

    记录学习React时自己是如何挖坑把自己埋了的过程:children以及其它props被修改时相关组件无法重新渲染(做了两天) 父组件代码: class UserHome extends Compon ...

  2. android黑科技系列——修改锁屏密码和恶意锁机样本原理分析

    一.Android中加密算法 上一篇文章已经介绍了Android中系统锁屏密码算法原理,这里在来总结说一下: 第一种:输入密码算法 将输入的明文密码+设备的salt值,然后操作MD5和SHA1之后在转 ...

  3. 为React绑定事件,并修改state中的值

    import React from 'react' export default class ClickS extends React.Component { constructor () { sup ...

  4. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  5. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析[转]

    前面在介绍Android系统的开机画面时提到,Android设备的显示屏被抽象为一个帧缓冲区,而Android系统中的SurfaceFlinger服务就是通过向这个帧缓冲区写入内容来绘制应用程序的用户 ...

  6. AbstractQueuedSynchronizer的介绍和原理分析(转)

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  7. 消息队列NetMQ 原理分析4-Socket、Session、Option和Pipe

    消息队列NetMQ 原理分析4-Socket.Session.Option和Pipe 前言 介绍 目的 Socket 接口实现 内部结构 Session Option Pipe YPipe Msg Y ...

  8. Redis事务原理分析

    Redis事务原理分析 基本应用 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD ...

  9. java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析

    java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...

随机推荐

  1. 中文NER的那些事儿5. Transformer相对位置编码&TENER代码实现

    这一章我们主要关注transformer在序列标注任务上的应用,作为2017年后最热的模型结构之一,在序列标注任务上原生transformer的表现并不尽如人意,效果比bilstm还要差不少,这背后有 ...

  2. vue中使用echarts,地图上的涟漪特效大小设置

    在使用echarts进行开发大屏时,使用到了地图这个组件 我们会根据返回的值来决定涟漪的大小 这时则使用 其它的value为返回的数组,一般格式为[经度,维度,值] 这样就能动态设置效果的大小了

  3. AnnotationConfigApplicationContext(1)之初始化Scanner和Reader

    AnnotationConfigApplicationContext(1)初始化Scanner和Reader 我们以AnnotationConfigApplicationContext为起点来探究Sp ...

  4. [loj2265]最长上升子序列

    以下内容参考2019年集训队论文<浅谈杨氏矩阵在信息学竞赛中的应用> 1.前置知识 杨表 标准杨表:一张网格图,满足以下条件-- 1.设其有$m$行.第$i$行有$a_{i}$个格子(格子 ...

  5. [gym101981F]Frank

    在本题中,每一步是独立的,因此即可以看作从$s$移动到$t$的期望步数(对于每一对$s$和$t$都求出答案) 令$f_{i,j}$表示当$s=i$且$t=j$时的答案,则有$f_{i,j}=\begi ...

  6. [GYCTF2020]Easyphp

    知识点 反序列化pop链 反序列化字符逃逸 解题过程 www.zip 备份文件获取源码 审计代码构造pop链 <?php Class UpdateHelper{ public $id; publ ...

  7. Redis分布式缓存剖析及大厂面试精髓v6.2.6

    概述 官方说明 Redis官网 https://redis.io/ 最新版本6.2.6 Redis中文官网 http://www.redis.cn/ 不过中文官网的同步更新维护相对要滞后不少时间,但对 ...

  8. Vue 中使用 TypeScript 详细总结

    VUE 项目中使用 Typescript 第一节:项目起步 Vue 中使用 TypeScript 项目中主要使用到的第三方依赖 vue2 vue-class-component vue-propert ...

  9. python 字典 key 对应多个 value

    基本思路是,将key对应的value设置为list,将对应的值append进去. 示例: f=open("a1.txt") ha={} for i in f: i=i.strip( ...

  10. python 封装、绑定

    目录 python 封装.绑定 1.数据.方法的封装 2.隐藏属性 3.开放接口 4.绑定方法 1.对象的绑定 2.类的绑定(classmethod) 3.非绑定方法(staticmethod) 4. ...