React源码 memo Fragment StrictMode cloneElement createFactory
import {REACT_MEMO_TYPE} from 'shared/ReactSymbols';
export default function memo<Props>(
  type: React$ElementType,
  compare?: (oldProps: Props, newProps: Props) => boolean,
) {
  return {
    $$typeof: REACT_MEMO_TYPE,
    type,
    compare: compare === undefined ? null : compare,
  };
}
就是通过 func component 作为参数传入进来,然后可以传第二个参数,是 oldProps 和 newProps 的一个对比方法,return true or false 来判断他是否需要返回,就跟 shouldupdate 是同样的意思,返回一个对象,里面有 $$typeof,是 REACT_MEMO_TYPE。type 就是传入的 function component,然后 compare就是传入的第二个参数,所以跟之前的 ref , context 是一类的东西,最终实现的逻辑肯定是要到 react-dom 里面去实现,他的目的就是为了跟 PureComponent 类似的功能。
Fragment: REACT_FRAGMENT_TYPE
Fragment 就是一个 Symbole,没有什么特别的意义,Fragment 就是 <>,react 16 之后提供了我们 Fragment 这个几点,他非常方便的告诉 react 这里是有多个兄弟节点的,他本身就是一个 Symbol,没有特别的含义
StrictMode: REACT_STRICT_MODE_TYPE
export 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 copied
  const props = Object.assign({}, element.props);
  // Reserved names are extracted
  let 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 overridden
  let 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 props
    let 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 props
          props[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);
}
const props = Object.assign({}, element.props); 首先他把 props 复制过来,然后把 key 和 ref 也复制过来。这些东西复制过来之后再进行一个处理,其实就是创建一个新的 react element , 整体的过程个你 createElemnt 差不多。只是传入一个 element,他进行一个 clone 这么一个过程。
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 it
  factory.type = type;
  return factory;
}
createFactory 对于写 JSX 的人来说,几乎是不可能用到的,因为 createFactory 是对 createElement 的一个封装。createFactory 其实是 createElement 绑定了一个 type。比如我们要去创建一个 p 标签的节点, p 标签的节点如果使用 javascript 的 api 去创建,那么在使用 createElement 的时候都要先传入 p ,再传入 config ,再传入 children 。我们可以先创建一个 p 标签的 factory ,然后通过这个 factory 返回的方法,我们只需要传入 config,children 就可以创建一个 p 标签。而不需要重复的去传 p。但对于写 jsx 的人来说,没有任何的必要。
React源码 memo Fragment StrictMode cloneElement createFactory的更多相关文章
- React躬行记(16)——React源码分析
		React可大致分为三部分:Core.Reconciler和Renderer,在阅读源码之前,首先需要搭建测试环境,为了方便起见,本文直接采用了网友搭建好的环境,React版本是16.8.6,与最新版 ... 
- React源码剖析系列 - 生命周期的管理艺术
		目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理.本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(C ... 
- React源码解析:ReactElement
		ReactElement算是React源码中比较简单的部分了,直接看源码: var ReactElement = function(type, key, ref, self, source, owne ... 
- React 源码剖析系列 - 生命周期的管理艺术
		目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ... 
- react 源码之setState
		今天看了react源码,仅以记录. 1:monorepo (react 的代码管理方式) 与multirepo 相对. monorepo是单代码仓库, 是把所有相关项目都集中在一个代码仓库中,每个mo ... 
- React 源码剖析系列 - 不可思议的 react diff
		简单点的重复利用已有的dom和其他REACT性能快的原理. key的作用和虚拟节点 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ... 
- 读react源码准备
		git源码地址:https://github.com/facebook/react react 里面就是 react源码 react里面的react文件夹就是react源码,react源码非常的少,总 ... 
- react源码之render
		1.最近学习react源码,刚刚入门,看了render的原理,到了fiberRoot的创建 如图: 
- React源码之组件的实现与首次渲染
		react: v15.0.0 本文讲 组件如何编译 以及 ReactDOM.render 的渲染过程. babel 的编译 babel 将 React JSX 编译成 JavaScript. 在 ba ... 
随机推荐
- n8n 基于node 的流程自动化工具
			n8n 是基于node开发的流程自动化工具,提供了可视化的操作,我们可以用来集成不同的服务. 目前已经提供了很多的服务集成组件,同时我们也可以方便的自己扩展,后边会进行一个系统的 学习,同时介绍下使用 ... 
- linux帮助命令使用
			一. help使用 查看ls命令的帮助信息 ls --help # 查看全部 ls --help | less # 分页查看, q退出 二. man手册 同一命令存在于多个章 ... 
- Centos7将本地源更换为网易源
			百度搜索: 网易源 点击进入网易开源镜像站 1. 备份当前 repo 文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS- ... 
- Linux性能优化实战学习笔记:第十二讲
			一.性能优化方法论 不可中断进程案例 二.怎么评估性能优化的效果? 1.评估思路 2.几个为什么 1.为什么要选择不同维度的指标? 应用程序和系统资源是相辅相成的关系 2.性能优化的最终目的和结果? ... 
- Linux性能优化实战学习笔记:第三十二讲
			一.上节总结 专栏更新至今,四大基础模块的第三个模块——文件系统和磁盘 I/O 篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,并且热情地留言与讨论. 今天是性能优化的第四期. ... 
- JVM系列之五:垃圾回收
			. jdk1.7的堆内存 1. 堆(Java堆) 堆是java虚拟机所管理的内存中最大的一块内存区域,也是被各个线程共享的内存区域, 在JVM启动时创建,该内存区域存放了对象实例(包括基本类型的变量及 ... 
- python运维开发常用模块(三)DNS处理模块dnspython
			1.dnspython模块介绍: dnspython(http://www.dnspython.org/)是Python实现的一个DNS 工具包,它支持几乎所有的记录类型,可以用于查询.传输并动态更新 ... 
- ORA-12528: TNS:listener: all appropriate instances are blocking new connections
			Oracle问题:ORA-12528: TNS: 监听程序: 所有适用例程都无法建立新连接 问题原始描述: ORA-12528: TNS:listener: all appropriate insta ... 
- ng的动画过渡
			动画过渡两种方法 1.使用angular+animation实现 在app-module.ts中引入 BrowserAnimationsModule 1.import { BrowserAnimati ... 
- ZYNQ笔记(2):PS端——Hello World !
			PL端使用过后,来到了ZYNQ核心的部分:PS端,现在用Vivado软件对ZYNQ-7000开发板的PS端进行第一个程序设计:Hello World. 一.新建Vivado工程 1.打开Vivado, ... 
