React16源码: memo, Fragment, StrictMode, cloneElement, createFactory源码实现

memo


1 ) 概述

  • memo 在react 16.6 推出的一个API
  • 它的用意是让 function component,有一个类似 PureComponent 的一个功能
    • PureComponent 提供了 class component 组件类型
    • 在props没有变化的情况下,它可以不重新渲染
  • 目的是给 function component 做一个 PureComponent 的对标
  • 这个用法很简单,就不进行举例了

2 ) 源码解析

// memo.js/*** Copyright (c) Facebook, Inc. and its affiliates.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.*/import {REACT_MEMO_TYPE} from 'shared/ReactSymbols';import isValidElementType from 'shared/isValidElementType';
import warningWithoutStack from 'shared/warningWithoutStack';export default function memo<Props>(type: React$ElementType,compare?: (oldProps: Props, newProps: Props) => boolean,
) {if (__DEV__) {if (!isValidElementType(type)) {warningWithoutStack(false,'memo: The first argument must be a component. Instead ' +'received: %s',type === null ? 'null' : typeof type,);}}return {$$typeof: REACT_MEMO_TYPE,type,compare: compare === undefined ? null : compare,};
}
  • 可以看到 memo 是一个方法
  • 第一个参数 type 可以是 function component
  • 第二个参数 compare
    • 是一个 old props 和 new props 的对比方法
    • 返回值是 boolean,类似于 SCU
  • 最终的返回值是一个对象
    • $$typeofREACT_MEMO_TYPE
    • type,就是我们传入的 function component
    • compare 是我们传入的第3个参数
    • 所以它就跟之前的 forwardRef, context 差不多一类的东西
    • 最终它实现的逻辑肯定还是要到 react-dom 那边来实现的

Fragment


1 ) 概述

  • Fragment 实际上是一个 Symbol
  • 在我们项目代码中的 <></> 实际上等价于 <React.Fragment><React.Fragment />
  • 这是React 渲染函数 render 中返回的单个节点的约束和无用div节点的平衡处理

2 )源码

// React.jsFragment: REACT_FRAGMENT_TYPE,
  • 从概述中得知,本身这个节点没有任何的意义
  • 它也不会生成多余的节点,只是告诉 react 里面是有多个兄弟节点
  • 本身就是一个 Symbol,没有特殊的含义
  • 它的作用就是用于包裹节点

StrictMode


1 ) 概述

  • StrictMode 本质是一个组件
  • 它的作用是在渲染内部组件时,发现不合适的代码并给出提醒

2 )源码

  // React.jsStrictMode: REACT_STRICT_MODE_TYPE,
  • 实际上它也是一个 Symbol
  • 它就跟 ConcurrentMode 是差不多的意思
  • 它这个节点下面的所有子树都要按照某一种模式进行渲染
  • 对于其规则下面的所有子树的节点,会给我们提供一些过时的API的提醒
    • 比如说在某个节点下面,使用了 componentWilMount 这种将要过期的生命周期方法的时候
    • 它就会做出提醒,说你这个方法是不好的,你不应该这么去做
    • 它使用方式也是像 react component,所以影响的范围仅仅是它的子树
  • 类似于 ConcurrentMode, 在它的节点下面才会是有一个异步渲染情况

cloneElement


1 ) 概述

  • 对原 ReactElement 进行克隆处理
  • 返回一个新的ReactElement

2 )源码分析

直接定位在 ReactElement.js

  // ReactElement.jsexport function cloneElement(element, config, children) {invariant(!(element === null || element === undefined),'React.cloneElement(...): The argument must be a React element, but you passed %s.',element,);let propName;// Original props are copiedconst props = Object.assign({}, element.props);// Reserved names are extractedlet key = element.key;let ref = element.ref;// Self is preserved since the owner is preserved.const self = element._self;// Source is preserved since cloneElement is unlikely to be targeted by a// transpiler, and the original source is probably a better indicator of the// true owner.const source = element._source;// Owner will be preserved, unless ref is overriddenlet owner = element._owner;if (config != null) {if (hasValidRef(config)) {// Silently steal the ref from the parent.ref = config.ref;owner = ReactCurrentOwner.current;}if (hasValidKey(config)) {key = '' + config.key;}// Remaining properties override existing propslet defaultProps;if (element.type && element.type.defaultProps) {defaultProps = element.type.defaultProps;}for (propName in config) {if (hasOwnProperty.call(config, propName) &&!RESERVED_PROPS.hasOwnProperty(propName)) {if (config[propName] === undefined && defaultProps !== undefined) {// Resolve default propsprops[propName] = defaultProps[propName];} else {props[propName] = config[propName];}}}}// Children can be more than one argument, and those are transferred onto// the newly allocated props object.const childrenLength = arguments.length - 2;if (childrenLength === 1) {props.children = children;} else if (childrenLength > 1) {const childArray = Array(childrenLength);for (let i = 0; i < childrenLength; i++) {childArray[i] = arguments[i + 2];}props.children = childArray;}return ReactElement(element.type, key, ref, self, source, owner, props);}
  • 首先,它把props首先复制过来,const props = Object.assign({}, element.props);
  • 然后呢把key和 ref 也复制过来 然后再进行一些处理
  • 其实就是创建一个新的 React Element
  • 其实整体的过程是跟 createElement 是差不多的
  • 只不过它是传入了一个 element,然后他进行一个克隆这么一个过程

createFactory


1 ) 概述

  • 返回一个某种类型的 ReactElement 工厂函数
  • 可以利用返回的函数来创建一个 ReactElement

2 )源码分析

export function createFactory(type) {const factory = createElement.bind(null, type);// Expose the type on the factory and the prototype so that it can be// easily accessed on elements. E.g. `<Foo />.type === Foo`.// This should not be named `constructor` since this may not be the function// that created the element, and it may not even be a constructor.// Legacy hook: remove itfactory.type = type;return factory;
}
  • 这个源码比较简洁
  • createFactory 对于写 jsx 的场景几乎是不可能用到的
  • 因为 createFactory 是对 createElement 的一个封装
    • createFactorycreateElement 绑定了一个type
    • 比如说我们要去创建一个p标签的节点
      • 如果使用 JS API去创建,比如使用 createElement
      • 每次都要先传入 p,然后再传入 config,再传入它的children
  • 其实,我们可以先创建一个p标签的 factory
    • 通过这个factory返回的方法,我们只需要传入config和children,就可以创建一个p标签
    • 而不需要重复的去传p这个字符串来表示我们要创建的是p标签的节点

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode-剑指offer】--15.找到字符串中所有字母异位词

15.找到字符串中所有字母异位词 方法&#xff1a;滑动窗口 class Solution {public List<Integer> findAnagrams(String s, String p) {List<Integer> ans new ArrayList<>();int m s.length(),n p.length();if(n > m){return ans;}int[] cnt1 new i…

认真学SQL——MySQL入门之表中约束——约束数据的插入和删除

-- 1.主键约束 primary key 特点: 限制主键插入的数据不能为空,不能重复 建表的时候添加主键约束: create table 表名(主键名 主键类型 primary key , 其他字段...); 注意: 一个表中只能有一个主键 --增 方式一&#xff1a;建表时(推荐使用) create table stu1( id in…

网络通信(4)-数据链路层解析

目录 一、概念 二、数据链路层的作用 三、数据链路层的三个基本问题

YoloV7改进策略:AAAI 2024 最新的轴向注意力|即插即用,改进首选|全网首发,包含数据集和代码,开箱即用!

摘要 https://arxiv.org/pdf/2312.08866.pdf 本文提出了一种名为Multi-scale Cross-axis Attention(MCA)的方法,用于解决医学图像分割中的多尺度信息和长距离依赖性问题。该方法基于高效轴向注意力,通过计算两个平行轴向注意力之间的双向交叉注意力,更好地捕获全局信息。…

无人机集群反制与对抗技术探讨

源自&#xff1a;指挥与控制学报 作者&#xff1a;任 智 张 栋 唐 硕 王孟阳 李智军 “人工智能技术与咨询” 发布 摘 要 无人机集群系统是现代信息化战争体系对抗中重要的新质作战力量, 是未来网络化、智能化作战的关键发展方向. 随着无人集群系统装备实战化技术的…

第二十七章 正则表达式

第二十七章 正则表达式 1.正则快速入门2.正则需求问题3.正则底层实现14.正则底层实现25.正则底层实现36.正则转义符7.正则字符匹配8.字符匹配案例19.字符匹配案例211.选择匹配符&#xff08;|&#xff09;12.正则限定符{n}{n,m}&#xff08;1个或者多个&#xff09;*(0个或者多…

『华为云耀云服务器实战』|云服务器如何快速搭建个人博客(图文详解)

文章目录 引言一、云耀云服务器L实例介绍1.1 准备一个华为云耀云服务器1.2 重置实例密码1.3 利用xshell 远程连接 二、安装环境软件2.1 安装git准备远程拉取2.2 安装Docker 和 Docker compose 三、博客开源项目介绍3.1 操作界面展览 四、拉取项目搭建个人博客4.1 拉取项目进行配…

【linux kernel】linux的SPI框架分析

文章目录 一、linux内核中的SPI框架二、SPI核心的初始化三、SPI核心的数据结构1、struct spi_statistics2、struct spi_delay3、struct spi_device4、struct spi_driver5、struct spi_controller6、struct spi_res7、struct spi_transfer8、struct spi_message9、struct spi_bo…

CMake支持的编译平台和IDE

文章目录 简介支持的IDEVisual Studio支持示例 其他编译器和生成器支持MinGW示例 IDE集成Eclipse示例 实验性和特殊平台支持总结 简介 CMake是一个非常强大的跨平台自动化构建工具&#xff0c;它支持生成多种类型的项目文件&#xff0c;覆盖了广泛的开发环境和编译器。在这篇博…

基于PCA-WA(Principal Component Analysis-weight average)的图像融合方法 Matlab代码及示例

摘要&#xff1a; 高效地将多通道的图像数据压缩&#xff08;如高光谱、多光谱成像数据&#xff09;至较低的通道数&#xff0c;对提高深度学习&#xff08;DL&#xff09;模型的训练速度和预测至关重要。本文主要展示利用PCA降维结合weight-average的图像融合方法。文章主要参…

leetcode第206题反转链表❤

一&#xff1a;题目&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网…

互补滤波简述

互补滤波也可以用来做IMU的姿态解算&#xff0c;它相比于卡尔曼滤波计算更简单&#xff0c;实时性更好&#xff0c;但精度不如卡尔曼滤波。 互补滤波的原理是利用了角度计算中加速度计和陀螺仪的特点&#xff0c;即加速度计长时间更准确&#xff0c;陀螺仪短时间更准确&#x…

【OpenCV】在MacOS上源码编译OpenCV

在MacOS上源码编译OpenCV 1. 下载项目源码2. 创建CMake编译文件3. 编译安装4. 案例测试5. 总结 前言 在做视觉任务时&#xff0c;我们经常会用到开源视觉库OpenCV&#xff0c;OpenCV是一个基于Apache2.0许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件…

js中函数动态调用

文章目录 一、场景二、方法2.1、动态函数2.2、eval()函数 三、最后 一、场景 在JS开发中&#xff0c;例如有些场景下&#xff0c;后端要求一个功能要请求不同的接口&#xff0c;但是传参及后续逻辑其实都是一样的&#xff0c;有些同学可能会想到在接口url处统一处理就好&#…

在 docker 容器中配置双网卡,解决通讯的问题

目录 1. 查看当前网络信息 2. 创建自定义网络 3. 查看网卡信息 4. 建立双网卡模式 5. 查看容器的网络 6. 从双网卡中删除默认网卡 已经创建好了的 Docker 容器&#xff0c;要修改它的IP比较麻烦&#xff0c;网上找了几种不同的方法&#xff0c;经过试验都没有成功&…

HeyGen怎么使用想使用高级功能如何订阅

HeyGen是一款AI视频工具&#xff0c;可以让用户轻松地用不同语言说话。 HeyGen是一个用于生成“虚拟化身&#xff08;数字人&#xff09;”视频的工具。 根据其官网的介绍&#xff0c;HeyGen可以通过文本生成视频&#xff0c;有不同的视频模板&#xff0c;可以定制化人物形象、…

Android Studio报错:connect refused

报错信息 解决办法&#xff1a;在System settings里取消代理&#xff0c;将HTTP Proxy设置为 No proxy 但是我发现我的还不行&#xff0c;还是报错&#xff0c;还是connect refused&#xff1a; 我发现虽然在System settings里已经取消代理&#xff0c;但实际项目运行时还是走…

鸿蒙原生应用/元服务开发-Serverless账户验证码的问题

在应用/元服务早期使用过程中&#xff0c;-Serverless账户验证码的格式是[AGC][应用/元服务名称]&#xff0c;如下图。 但是&#xff0c;在最近&#xff0c;[应用/元服务]名称直接变成了【default】,用户收到这种验证码后&#xff0c;心里存有疑虑的&#xff0c;这是哪里配置…

OSG-渲染状态、纹理映射(一)

1、渲染状态 OSG 支持绝大部分的OpenGL固定功能管道(fixed function pipeline)渲染,如Alpha检验、Blending融合剪切平面、颜色蒙板、面选(face culling)深度和模板检验、雾效、点和线的光栅化(rasterization)等。OSG 的渲染状态也允许应用程序指定顶点着色(vertex shader)和片段…

墙裂分享的免费好用api接口

企业工商三要素核验 API&#xff1a;通过输入企业名称、法人、注册号 /组织机构代码 /统一社会信用代码&#xff0c;验证三者是否匹配一致。企业工商四要素核验&#xff1a;传入企业名称、社会统一信用代码、法人名称、法人身份证&#xff0c;校验此四项是否一致。空气质量查询…