zoukankan      html  css  js  c++  java
  • React源码 memo Fragment StrictMode cloneElement createFactory

    1、memo
    react 16.6 推出的 api ,他的用意是给 function component 也有 PureComponent 这样一个类似的功能,因为我们知道 PureComponent 提供了 class component 的组件类型,在 props 没有变化的情况下,他可以不重新渲染,对于 func component 因为他不存在一些生命周期之类的东西,所以他也没有继承这个说法,他之前都没有提供类似这样的功能,那么现在 React 提供了这么一个方法,
    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 类似的功能。

    2、Fragment
    Fragment: REACT_FRAGMENT_TYPE

    Fragment 就是一个 Symbole,没有什么特别的意义,Fragment 就是 <>,react 16 之后提供了我们 Fragment 这个几点,他非常方便的告诉 react 这里是有多个兄弟节点的,他本身就是一个 Symbol,没有特别的含义

    3、StrictMode
    StrictMode: REACT_STRICT_MODE_TYPE
    他也是一个 symbol ,他跟 ConcurrentMode 差不多一个意思。他标识这他的每个子组件都按照某种模式进行一个渲染,对于 StrictMode 来讲,下面的所有子组件的节点,他会给我们提供一些过时的 api 的提醒,比如这个节点像使用 componentWillMount 这种将要过期的声明周期方法的时候,他就会给我们做出提醒说,这个方法是不好的,不要这么去做,他使用也跟 react component 一样,他影响的范围也只会影响子组件
    4、cloneElement
    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 这么一个过程。

    5、createFactory
    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 的人来说,没有任何的必要。

  • 相关阅读:
    手动安装mysql
    spring boot 配置注入
    IOS-电话拦截
    重新入坑-IntelliJ Maven
    git使用问题
    Intelij U
    iTunes空间不足无法备份iphone的问题
    Centos7最小化安装
    实操笔记
    centos7中端口及服务对应情况(笔记)
  • 原文地址:https://www.cnblogs.com/wzndkj/p/11963905.html
Copyright © 2011-2022 走看看