React之state详解

目录

执行过程

异步

React18与自动批处理

setState

推荐用法 ()=>{return },this.state. 

生命周期

数据没改变时​不渲染

shouldComponentUpdate 

PureComponent自动(推荐)

你真的理解setState吗? - 掘金

组件的私有属性,值是对象,当 state 发生变化时会触发 React 组件重新渲染视图

响应式数据

执行过程

  • _pendingStateQueue当前组件等待执行更新的state队列
  • isBatchingUpdates:react用于标识当前是否处于批量更新状态,所有组件公用
  • dirtyComponent:当前所有处于待更新状态的组件队列

事务机制:数据库特有的术语,同步发生数据更新时,防止数据的不一致。

1.将setState传入的partialState参数存储在当前组件实例state暂存队列中。

2.判断当前React是否处于批量更新状态,如果是,将当前组件加入待更新的组件队列中。

3.如果未处于批量更新状态,将批量更新状态标识设置为true,用事务再次调用前一步方法,保证当前组件加入到了待更新组件队列中。

4.调用事务的waper方法,遍历待更新组件队列依次执行更新。

5.执行生命周期componentWillReceiveProps

6.将组件的state暂存队列中的state进行合并,获得最终要更新的state对象,并将队列置为空。

7.执行生命周期componentShouldUpdate,根据返回值判断是否要继续更新。

8.执行生命周期componentWillUpdate

9.执行真正的更新render

10.执行生命周期componentDidUpdate

异步

setState其实本身执行的过程和代码都是同步的

自动批处理:同一时机多次调用`setState()`方法的一种处理机制,有助于减少在状态更改时发生的重新渲染次数。

handleClick = () => {  
    this.setState({
        msg: 'hi'
    });
    this.setState({
        count: 1
    });
}

//虽然调用了两次`setState()`方法,但是只会触发一次`render()`方法的重新执行。

React18与自动批处理

React18之前也有批处理的,但是在Promise、setTimeout、原生事件中是不起作用的,只在合成事件和钩子函数有用

原生自带的事件监听 addEventListener ,或者也可以用原生js、jq直接 document.querySelector().onclick 这种绑定事件的形式都属于原生事件。

react为了解决跨平台,兼容性问题,自己封装了一套事件机制,代理了原生的事件。

像在jsx中常见的onClickonChange这些都是合成事件

handleClick = () => {  
    setTimeout(()=>{
        this.setState({
            msg: 'hi'
        });
        this.setState({
            count: 1
        });
    }, 2000)
}

//上面代码在React18之前的版本中,将会触发两次`render()`方法。
//默认是自动批处理的,当然也可以改成不是自动批处理的方式,通过`ReactDOM.flushSync`这个方法。
import { flushSync } from 'react-dom'; // Note: react-dom, not react
handleClick = () => {  
    ReactDOM.flushSync(()=>{
        this.setState({
            msg: 'hi'
        });
    })
    ReactDOM.flushSync(()=>{
        this.setState({
            count: 1
        });
    }) 
}

 useState(initialState: S | (() => S));

let { useState } = React;
let { flushSync } = ReactDOM;
let Welcome = (props) => {
    const [count, setCount] = useState(0);
    const handleClick = () => {
        flushSync(()=>{
          setCount(count + 1)
        })
    }
    return (
        <div>
            <button onClick={handleClick}>点击</button>
            <div>hello world, { count }, { msg }</div>
        </div>
    );
}

当所有组件didmount后,父组件didmount,会将isBranchUpdate设置为false。这时将执行之前累积的setState,更新时会把每个组件的更新合并,每个组件只会触发一次更新的生命周期。

setState

setState(state: (prevState, props) => (return newState),callback?: () => void): void;

状态更新完成后会调用该回调函数callback

props 同步更新,state 异步更新的,最好不要用prevState值去计算下一个 state 的值

this.setState((prevState, props) => {  return { count: prevState.count + 1 }})

state:如果是一个对象,那么会将该对象与原状态进行浅合并

this.setState({count:1}) 
//箭头函数:相当于直接使用返回对象 {count: 1}
this.setState(() => ({count: 1}));
//同样的数据修改只会修改一次,可利用`setState()`的回调函数写法来保证每一次都能触发。
//因为不能比较函数体是否一致
this.setState((state)=> ({count: state.count + 1}));
this.setState((state)=> ({count: state.count + 1}));

合并(shallow merge)是指将两个对象进行合并,如果两个对象有相同的属性名,则后一个对象的属性值会覆盖前一个对象的属性值

但是,如果属性值是一个对象,则不会进行递归合并,而是直接用后一个对象的属性值替换前一个对象的属性值。

useState不会合并之前的值

const [info, setInfo] = useState({
    username: 'xiaoming',
    age: 20
})
setInfo({
    ...info,
    username: 'xiaoqiang'
})

推荐用法 ()=>{return },this.state. 

setState时使用函数返回新state值,(避免多个 setState 同时调用导致的状态更新冲突问题)

回调函数中获取最新更新后的state

handleClick = () => {
    this.setState(() => { return { board: this.jsonMsg[0].data.board_data[Number(key)] };}, 
() => {
      console.log('Updated count:', this.state.count);
    });
  };

生命周期

生命周期钩子函数就是回调函数

挂载

  • constructor():在 React 组件挂载之前,会调用它的构造函数。(注:如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。)
  • render(): class 组件中唯一必须实现的方法。
  • componentDidMount():在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。

更新

  • render(): class 组件中唯一必须实现的方法。一旦组件被添加到 DOM,它只有在 prop 或状态发生变化时才可能更新和重新渲染
  • componentDidUpdate():在更新后会被立即调用。首次渲染不会执行此方法。

卸载

  • componentWillUnmount():在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。
     

可以看到挂载时和更新时都有render这个方法。这就是为什么state改变的时候,会触发render重渲染操作

数据没改变时​不渲染

shouldComponentUpdate 

在调用`setState()`方法的时候,如果数据没有改变,实际上也会重新触发`render()`方法。

shouldComponentUpdate = (nextProps, nextState) => {
        if(this.state.msg === nextState.msg){
            return false;
        }
        else{
            return true;//重新渲染
        }
    }

PureComponent自动(推荐)

自动完成选择性的渲染

export default class App extends PureComponent<any, any, any>{
 handleClick = () => {  
        this.setState({
          list: [...this.state.list, 'd']
        }); 
        //错误✖
        /* this.state.list.push('d');
        this.setState({
          list: this.state.list
        }) */
    }
} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/31414.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何在Microsoft Excel中使用LEN函数

如果你曾经想尝试查找一行文本中的字符数&#xff0c;你可以使用Microsoft Excel来查找&#xff0c;这要归功于LEN函数。以下是如何使用它。 一、什么是 LEN 函数 LEN函数是一个简单的计算函数&#xff0c;用于计算给定文本字符串中的所有字符&#xff0c;包括数字、字母、特…

内网安全:内网穿透详解

目录 内网穿透技术 内网穿透原理 实验环境 内网穿透项目 内网穿透&#xff1a;Ngrok 配置服务端 客户端配置 客户端生成后门&#xff0c;等待目标上线 内网穿透&#xff1a;Frp 客户端服务端建立连接 MSF生成后门&#xff0c;等待上线 内网穿透&#xff1a;Nps 服…

三、Docker命令及基本使用

学习参考&#xff1a;尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出) 目录 前言一、帮助启动类命令1.1 启动docker1.2 停止docker1.3 重启docker1.4 查看docker状态1.5 开机启动1.6 查看docker概要信息1.7 查看docker总体帮助文档1.8 查看docker命令…

autoDL上A100运行wiki出错:NVIDIA A100-PCIE-40GB(最后安装好torch+dgl了);学校服务器加2.X版本pytorch

1、A100运行wiki出错&#xff1a;NVIDIA A100-PCIE-40GB with CUDA capability sm_80 is not compatible with the current PyTorch installation. The current PyTorch install supports CUDA capabilities sm_37 sm_50 sm_60 sm_70. If you want to use the NVIDIA A100-PCIE…

题集-栈和队列的相互转化

这里&#xff0c;队列的性质是先入先出&#xff0c;但是栈的性质是后入先出。两个队列就可以通过相互捯实现数据的后入先出。 typedef int QDataType&#xff1b; //这是一个队列结点的结构 typedef struct QueueNode { struct QueueNode* next; QDataType data; }QNode; //这是…

常见面试题之MySQL篇

1.MySQL中&#xff0c;如何定位慢查询? 我们当时做压测的时候有的接口非常的慢&#xff0c;接口的响应时间超过了2秒以上&#xff0c;因为我们当时的系统部署了运维的监控系统Skywalking&#xff0c;在展示的报表中可以看到是哪一个接口比较慢&#xff0c;并且可以分析这个接…

ChatGPT在前,华为盘古Chat在后

国产盘古Chat对话方面堪比GPT-3.5 什么是ChatGPT&#xff1f;简单来说&#xff0c;就是一个能够和人类自然对话的人工智能系统。它可以理解你的语言&#xff0c;回答你的问题&#xff0c;甚至给你提供建议和服务。它不仅可以处理文字&#xff0c;还可以处理图片、视频、音频等…

Web3 是什么?为何应该关注?

当我开始我的职业生涯时&#xff0c;“Web2.0”还是一个热门的新事物。 当我开始我的职业生涯时&#xff0c;正值互联网快速发展的时期&#xff0c;人们谈论的是“Web2.0”&#xff0c;这一概念引发了许多关于用户参与、社交媒体和在线合作的讨论。然而&#xff0c;随着时间的推…

DataStructure01|ArrayList和顺序表

ArrayList与顺序表 1.线性表 ​ 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列… ​ 线性表在逻辑上是线性结构&#xff0c;也就说…

掌握Python的X篇_4_开发工具ipython与vscode的安装使用

本篇将会介绍两个工具的安装及使用来提高Python的编程效率。 ipython&#xff1a;比python更好用的交互式开发环境vscode&#xff1a;本身是文本编辑器&#xff0c;通过安装相关的插件vscode可以作为python集中开发环境使用 掌握Python的X篇_4_开发工具ipython与vscode的安装使…

ChatGPT/GPT-4 或将从根本上改变软件工程

文章目录 一、前言二、主要内容 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 编程也可能是最容易被 AI 技术取代的工作之一&#xff0c;软件的构建方式将产生根本性的转变。 今年以来&#xff0c;相信大家都听说过 ChatGPT、New Bing 和…

Java try-catch块

Java的try块用于封装可能会抛出异常的代码。它必须在方法内部使用。 如果在try块中的特定语句处发生异常&#xff0c;后续的代码块将不会执行。因此&#xff0c;建议不要在try块中放置不会抛出异常的代码。 Java的try块必须后跟catch块或finally块。 Java try-catch语法 try…

chatgpt赋能python:Python绘制车辆轨迹图

Python绘制车辆轨迹图 在现代交通中&#xff0c;车辆轨迹图是一个广泛应用的技术&#xff0c;它可以被用于道路交通管理&#xff0c;行车安全评估等领域。Python是一种强大的编程语言&#xff0c;它提供了许多绘制数据可视化图表的库。本文将介绍如何使用Python和Matplotlib库…

Git的使用方法

文章目录 Git简介Git用法上传到gitee上 Git简介 简单来说&#xff0c;Git就像一个日志一样&#xff0c;可以帮你记录你对文本文件的修改&#xff0c;但他的功能又强于日志&#xff0c;不仅可以记录&#xff0c;还可以帮你存储那些你对文本文件的修改&#xff0c;当你想要找回之…

ArcGis系列-坐标系转换

Arcgis的工程项目可以添加各种类型的空间资源&#xff0c;比如数据库空间表、shp文件&#xff0c;每张空间表的坐标系可能都会有差异&#xff0c;把他们放到一个工程里时可以统一设置坐标系。 本文将介绍ArcGis三个需要坐标转换的场景&#xff1a; Arcgis Pro设置项目坐标GP分…

论文笔记--GPT-4 Technical Report

论文笔记--GPT-4 Technical Report 1. 报告简介2. 报告概括3 报告重点内容3.1 Predictable Scaling3.2 Capabilities3.3 limitations3.3 Risks & mitigations 4. 报告总结5. 报告传送门6. References 1. 报告简介 标题&#xff1a;GPT-4 Technical Report作者&#xff1a;…

【ABAP】数据类型(四)「类型组TYPE-POOL」

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后端的开发语言ABAP,SQL进行任务的完成,对SAP企业管理系统,SAP ABAP开发和数据库具有较…

Mac安装chromedriver

一、chromedriver下载 1、打开chrome浏览器输入&#xff1a;chrome://settings/help 查看当前chrome版本     2、下载对应的chromedriver版本 下载地址&#xff1a;http://chromedriver.storage.googleapis.com/index.html 选择mac系统的chromedriver 直接解压该文件 3、…

SpringBoot使用MockMVC单元测试Controller

前言&#xff1a; 在SpringBoot应用程序中&#xff0c;Controller是接受客户端请求并返回响应数据的核心组件。为了保证Controller的正确性和稳定性&#xff0c;我们可以使用MockMVC框架进行单元测试。MockMVC是Spring框架提供的一个HTTP客户端&#xff0c;用于模拟HTTP请求和响…

华为云“企业快成长大数据与微服务技术创新论坛”成功举办

6月16日&#xff0c;由华为云、msup、厦门火炬大学堂、厦门市行业软件协会联合主办的“企业快成长大数据与微服务技术创新论坛”在厦门成功举办。本次活动汇聚了华为云、珍爱网等知名企业的CTO和技术专家&#xff0c;通过技术案例解析了大数据平台构建、微服务演进等内容&#…