c/c++语言开发共享详解React中Props的浅对比

上一周去面试的时候,面试官我purecomponent里是如何对比props的,概念已经牢记脑中,脱口而出就是浅对比,接着面试官问我是如何浅对比的,结果我就没回答上来。趁着周末,再来看看源码里是如何实

上一周去面试的时候,面试官我purecomponent里是如何对比props的,概念已经牢记脑中,脱口而出就是浅对比,接着面试官问我是如何浅对比的,结果我就没回答上来。

趁着周末,再来看看源码里是如何实现的。

类组件的props对比

类组件是否需要更新需要实现shouldcomponentupdate方法,通常讲的是如果继承的是purecomponent则会有一个默认浅对比的实现。

  // reactbaseclasses.js  function componentdummy() {}  componentdummy.prototype = component.prototype;    /**   * convenience component with default shallow equality check for scu.   */  function purecomponent(props, context, updater) {    this.props = props;    this.context = context;    // if a component has string refs, we will assign a different object later.    this.refs = emptyobject;    this.updater = updater || reactnoopupdatequeue;  }    const purecomponentprototype = (purecomponent.prototype = new componentdummy());  purecomponentprototype.constructor = purecomponent;  // avoid an extra prototype jump for these methods.  object.assign(purecomponentprototype, component.prototype);  purecomponentprototype.ispurereactcomponent = true;  

purecomponent的实现如上,我以前以为在声明时默认会实现shouldcomponentupdate方法,但实际上并没有一个默认的方法。

接下来看看shouldcomponentupdate方法的调用。

  // reactfiberclasscomponent.js  function checkshouldcomponentupdate(    workinprogress,    ctor,    oldprops,    newprops,    oldstate,    newstate,    nextcontext,  ) {    const instance = workinprogress.statenode;    // 如果实利实现了shouldcomponentupdate则返回调用它的结果    if (typeof instance.shouldcomponentupdate === 'function') {      const shouldupdate = instance.shouldcomponentupdate(        newprops,        newstate,        nextcontext,      );      return shouldupdate;    }      // purereactcomponent的时候进行浅对比    if (ctor.prototype && ctor.prototype.ispurereactcomponent) {      return (        !shallowequal(oldprops, newprops) || !shallowequal(oldstate, newstate)      );    }      return true;  }  

可以看出实际上并没有单独写一个shouldcomponentupdate方法给purereactcomponent,而是在对比的时候就返回浅对比的结果。

浅对比的答案都在shallowequal方法里了。

shallowequal 浅对比

  // shallowequal.js  function shallowequal(obja: mixed, objb: mixed): boolean {    // 一样的对象返回true    if (object.is(obja, objb)) {      return true;    }      // 不是对象或者为null返回false    if (      typeof obja !== 'object' ||      obja === null ||      typeof objb !== 'object' ||      objb === null    ) {      return false;    }      const keysa = object.keys(obja);    const keysb = object.keys(objb);      // key数量不同返回false    if (keysa.length !== keysb.length) {      return false;    }      // 对应key的值不相同返回false    for (let i = 0; i < keysa.length; i++) {      if (        !hasownproperty.call(objb, keysa[i]) ||        !object.is(obja[keysa[i]], objb[keysa[i]])      ) {        return false;      }    }      return true;  }  

shallowequal方法原理很简单了

  1. 先判断两者是否为同一对象。
  2. 判断两者的值是否不为object或为null。
  3. 对比两者key的长度。
  4. 判断两者key对应的值是否相同。

原来原理是这样简单的对比,如果我面试的时候能够口喷源码,会不会工资更高一些呢?

函数组件的浅对比

函数组件的浅对比方式则使用react.memo方法实现。

  // reactmemo.js  export function memo<props>(    type: react$elementtype,    compare?: (oldprops: props, newprops: props) => boolean,  ) {    const elementtype = {      $$typeof: react_memo_type,      type,      compare: compare === undefined ? null : compare,    };    return elementtype;  }  

react.memo方法同样支持传入compare函数最为第二个参数。

内部的处理其实是手动创建了一个$$typeof为react_memo_type的reactelement,方便之后的类型判断。

react.memo组件的创建会稍微复杂一些,由于可以传入第二个自定义的compare函数,所以在内部其实会被定义为2种类型的fiber节点。

  • 没有传入compare函数的为simplememocomponent。
  • 传入了自定义compare函数的为memocomponent。

但是实际对于props的比较都是相同的,默认都是调用shallowequal方法来对比。

updatesimplememocomponent

  if (    shallowequal(prevprops, nextprops) &&    current.ref === workinprogress.ref  ) {  	// ...  }  

updatememocomponent

  // ...  let compare = component.compare;  compare = compare !== null ? compare : shallowequal;  if (compare(prevprops, nextprops) && current.ref === workinprogress.ref) {    return bailoutonalreadyfinishedwork(current, workinprogress, renderlanes);  }  // ...   

至于为什么要分为2个组件,我也没大看懂,蓝廋香菇,大概是和更新调度相关的。

simplememocomponent的fiber节点实际等于改了个名的函数组件,走流程会直接走到函数组件里,而memocomponent则是套了一层壳,需要先把壳剥开生成子fiber节点,再由子fiber节点的判断走到函数组件里。

以上就是props浅对比的分析了~

以上就是详解react中props的浅对比的详细内容,更多关于react中props的浅对比的资料请关注<计算机技术网(www.ctvol.com)!!>其它相关文章!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/595586.html

(0)
上一篇 2021年5月8日
下一篇 2021年5月8日

精彩推荐