React 原理
函数式编程
- 纯函数
reducer必须是一个纯函数,即没有副作用的函数,不修改输入值,相同的输入一定会有相同的输出 - 不可变值
state必须是不可变值,否则在shouldComponentUpdate中无法拿到更新前的值,无法做性能优化操作。
vdom 和 diff 算法
JSX 本质
- 是
React.createElement函数React.createElement(tag, props, child1, child2, child3)React.createElement(tag, props, [child1, child2, child3])
- 执行生成
vnode
const elem = <div><p>aaa</p><p style={{ color: 'red' }}>bbb</p></div>;
const elem = React.createElement("div", null, React.createElement("p", null, "aaa"), React.createElement("p", { style: { color: "red" } }, "bbb")
);
const lisElem = <div>{this.state.list.map((item, index) => {return (<span key={item.id}>{item.name}</span>);})}
</div>;
const listElem = React.createElement("div", null, (void 0).state.list.map((item, index) => {return React.createElement("span", { key: item.id }, item.name);})
);
合成事件
react的事件不是原生事件MouseEvent,而是合成事件SyntheticEventreact16是挂载到document上的;react17开始是挂载到root上的- 事件处理函数交给合成事件,事件冒泡到
document/root上进行处理
出处:https://coding.imooc.com/lesson/419.html#mid=41943
合成事件的好处:
- 更好的兼容性和跨平台:比如
react-native - 全部挂载到
document/root上,减少内存消耗,避免频繁解绑 - 方便事件的统一管理(事务机制)
出处:https://coding.imooc.com/lesson/419.html#mid=41943
React17 开始挂载到 root 组件上:
- document 只有一个,root 有多个,有利于多个 react 版本共存,例如:微前端
setState 和 batchUpdate
setState 主流程
出处:https://coding.imooc.com/lesson/419.html#mid=41943
- 异步:左边分支
- 非异步:右边分支
isBatchingUpdates
class ListDemo extends React.Componentconstructor(props) {// ...}render() {// ...}increase = () => {// 开始: 处于 batchUpdate// isBatchingiUpdates = true this.setState({count: this.state.count + 1});// 结束// isBatchingUpdates = false}
}
class ListDemo extends React.Componentconstructor(props) {// ...}render() {// ...}increase = () => {// 开始: 处于 batchUpdate// isBatchingUpdates = true setTimeout(() => {// 此时 isBatchingUpdates 是 falsethis.setState({count: this.state.count + 1});});// 结束// isBatchingUpdates = false}
}
componentDidMount() {// 开始: 处于 batchUpdate// isBatchingUpdates = true document.body.addEventListener('click', () => {// 此时 isBatchingUpdates 是 falsethis.setState({count: this.state.count + 1});console.log('count in body event', this.stae.count);});// 结束// isBatchingUpdates = false
}
哪些能命中 batchUpdate 机制:
- 生命周期(和它调用的函数)
React中注册的事件(和它调用的函数)React可以“管理”的入口
transaction 事务机制
class ListDemo extends React.Componentconstructor(props) {// ...}render() {// ...}increase = () => {// 开始:处于 batchUpdate// isBatchingUpdates = true// 其他任何操作// 结束// isBatchingUpdates = false}
}
出处:https://coding.imooc.com/lesson/419.html#mid=41943
transaction.initialize = function() {console.log('initialize');
};transaction.close = function() {console.log('close');
};function method() {console.log('abc');
}transaction.perform(method);// 输出 'initialize'
// 输出 'abc'
// 输出 'close'
react 组件渲染过程
JSX如何渲染为页面:- 初始化时候继承
props和 生成state - 通过
render()函数 生成vnode patch(elem, vnode):通过patch函数将vonde更新到dom上
- 初始化时候继承
setState之后如何更新页面:setSate(newState)->dirtyComponents(可能有子组件):通过setState产生新的state,存到dirtyComponent进行异步更新- 通过
render()函数生成新的vnode patch(elem, vnode):再通过patch函数用 newVnode 去更新旧的 vnode
react-fiber
react 的 patch 被拆分为两个阶段:
reconciliation阶段:执行diff算法,纯js计算commit阶段:将diff结果渲染成dom
背景
js是单线程的,且和dom渲染共用一个线程- 当组件足够复杂,组件更新时计算和渲染压力都很大
- 同时再有
dom操作需求,比如动画、鼠标拖拽等,那么将会卡顿
解决方案:fiber
fiber
react内部的运行机制,开发者体会不到- 将
reconciliation阶段进行任务拆分(commit无法拆分) dom需要渲染时暂停,空闲时恢复- 通过
window.requestidleCallback进行控制(并非所有浏览器支持)
FQA
JSX的本质是什么?jsx的本质是React.createElement函数,执行生返回vnode。
react组件更新渲染的过程。- 初始化时候继承
props和 生成state - 通过
render()函数生成vnode - 再通过
patch函数将vonde渲染成真实dom - 通过
setState修改产生新的state - 触发
re-render生成新的vnode - 再通过
patch函数用newVnode去更新旧的vnode
- 初始化时候继承
react为什么要将patch过程拆分成reconciliation和commit两个阶段?- 因为
js是单线程的,且和dom渲染共用一个线程 - 当组件很复杂的时候,组件更新时计算和渲染压力都很大
- 同时再有
dom操作需求,比如动画、鼠标拖拽等,那么将会卡顿
- 因为
相关文章:
React 原理
函数式编程 纯函数 reducer 必须是一个纯函数,即没有副作用的函数,不修改输入值,相同的输入一定会有相同的输出不可变值 state 必须是不可变值,否则在 shouldComponentUpdate 中无法拿到更新前的值,无法做性能优化操作…...
java高并发系列 - 第4天:JMM相关的一些概念
JMM(java内存模型),由于并发程序要比串行程序复杂很多,其中一个重要原因是并发程序中数据访问一致性和安全性将会受到严重挑战。如何保证一个线程可以看到正确的数据呢?这个问题看起来很白痴。对于串行程序来说,根本就是小菜一碟&…...
如何卸载旧版docker
环境: Docker1.13 centos7.6 问题描述: 如何卸载旧版docker 解决方案: 1.停止Docker服务。使用以下命令停止Docker服务: sudo service docker stop2.卸载Docker软件包。根据您的Linux发行版,使用适当的包管理器来…...
Wheeltec小车的开发实录(0)
配置静态ip(可以联网) 首先在你正常链接网络的时候打开“Connection Information”(我的是wifi,而且是手机热点,所以我手机就相当于一台路由器) 查看路由ip 观察到Default Route 是192.168.***.225这就是我手机的地址࿰…...
uniapp中uview组件库的NoticeBar 滚动通知 使用方法
目录 #平台差异说明 #基本使用 #配置主题 #配置图标 #配置滚动速度 #控制滚动的开始和暂停 #事件回调 #API #Props #Events 该组件用于滚动通告场景,有多种模式可供选择 #平台差异说明 AppH5微信小程序支付宝小程序百度小程序头条小程序QQ小程序√√√√…...
蓝桥杯每日一题----货物摆放
题目 分析 上来一看,三个for循环,从1到n,寻找满足lwhn的个数,但是这样根本跑不出来答案,n太大了,1e15的级别,O(n)的时间复杂度都不行,更何况是O(…...
(二十)Flask之上下文管理第一篇(粗糙缕一遍源码)
每篇前言: 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 🔥🔥本文已收录于Flask框架从入门到实战专栏:《Flask框架从入…...
Tensorflow2.0笔记 - 基础数学运算
本笔记主要记录基于元素操作的,-,*,/,//,%,**,log,exp等运算,矩阵乘法运算,多维tensor乘法相关运算 import tensorflow as tf import numpy as nptf.__version__#element-wise运算,对应元素的,-,*,/,**,//,% tensor1 tf.fill([3,3], 4) ten…...
年底聚餐无压力,HUAWEI WATCH GT 4 助力体形管理和健康守护
过了腊八就是年,逢年过节聚餐频繁。在品味美食、享受亲情温馨的同时,你是否也在担心自己的健康与体形呢?华为WATCH GT 4搭载心率监测、血氧检测和减脂塑形等功能,让你尽情享受美食的同时保持健康。 华为WATCH GT 4的心率监测功能…...
Tomcat Notes: URL Mapping
This is a personal study notes of Apache Tomcat. Below are main reference material. - YouTube Apache Tomcat Full Tutorial,owed by Alpha Brains Courses. https://www.youtube.com/watch?vrElJIPRw5iM&t801s 1、URL Mapping To Resources1.1、What w…...
【JVM】JVM概述
JVM概述 基本介绍 JVM:全称 Java Virtual Machine,即 Java 虚拟机,一种规范,本身是一个虚拟计算机,直接和操作系统进行交互,与硬件不直接交互,而操作系统可以帮我们完成和硬件进行交互的工作特…...
【2023开发组二等奖】湖南省国土空间规划双评价系统
作品介绍 1 需求分析 1.1 背景与意义 在我国辽阔的国土空间中,各地区的地形地势、自然条件和资源环境禀赋存在显著差异。然而,随着人口增长和城市化进程加快,高强度的不合理开发和产业布局广泛分布,使得部分地区的经济社会发展规模超过了资源环境的承载能力。因此,执行主…...
Flutter为什么不需要子线程——Dart IO源码剖析(上)
Dart IO 源码剖析 许多Flutter新手,特别是安卓、iOS原生开发转做Flutter的小伙伴,一直对Flutter 单线程模型开发APP倍感不解,他们总是喜欢本能的把网络请求、文件读写放到一个单独线程去做,因为“耗时操作会阻塞UI线程嘛”。于是…...
docker使用Dockerfile制做容器(以hyperf为列,开机启动)
1、Dockerfile文件 FROM hyperf/hyperf:8.1-alpine-v3.18-swoole WORKDIR /data MAINTAINER dade <dadeqq.com> ADD start.sh start.sh RUN chmod x ./start.sh CMD /data/start.sh1-1、执行命令生成hyperf:latest容器(文件名是Dockerfile可以省略࿰…...
PDF转PowerPoint - Java实现方法
通过编程实现PDF转PPT的功能,可以自动化转换过程,减少手动操作的工作量,并根据需要进行批量转换。将PDF文件转换为PPT文档后,可以利用PPT的丰富功能和动画效果,达到更好的演示效果。 在Java中,我们可以使用…...
【Spring之手写一个依赖注入容器】
Spring之手写一个依赖注入容器 1. 创建两个自定义注解1.1 Component注解1.2 DI注解 2. ApplicationContext接口与实现类2.1 ApplicationContext 接口2.2 实现类:DefaultListableApplicationContext 3. 定义DAO层和Service层及其实现4. 定义异常信息类4.1 InjectBean…...
kafka之java客户端实战
1. kafka的客户端 Kafka提供了两套客户端API,HighLevel API和LowLevel API。 HighLevel API封装了kafka的运行细节,使用起来比较简单,是企业开发过程中最常用的客户端API。 而LowLevel API则需要客户端自己管理Kafka的运行细节,Pa…...
图解渠道网关:不只是对接渠道的接口(一)
这是《百图解码支付系统设计与实现》专栏系列文章中的第(20)篇。点击上方关注,深入了解支付系统的方方面面。 主要讲清楚什么是渠道,有哪些类型的渠道,什么是渠道网关,渠道网关在支付系统中定位、核心功能…...
【js版数据结构学习之队列】
队列 一、简要认识队列二、队列的封装三、队列的应用1.栈和队列的转换2.全排列3.任务调度4.缓存管理 一、简要认识队列 结构:一种特殊的线性表 入队:在队尾插入一个元素 出队:在队头删除一个元素 特点:先入先出 空队列࿱…...
iOS Xcode 升级Xcode15报错: SDK does not contain ‘libarclite‘
iOS Xcode 升级Xcode15报错: SDK does not contain libarclite 一、仔细查看报错代码: SDK does not contain libarclite at the path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/ lib/arc/libarclite_iphonesimulator.a; try in…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...



