最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解React中Props的淺對(duì)比

 更新時(shí)間:2021年05月03日 10:44:21   作者:ZHANGYU  
這篇文章主要介紹了React中Props的淺對(duì)比的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下

上一周去面試的時(shí)候,面試官我PureComponent里是如何對(duì)比props的,概念已經(jīng)牢記腦中,脫口而出就是淺對(duì)比,接著面試官問(wèn)我是如何淺對(duì)比的,結(jié)果我就沒(méi)回答上來(lái)。

趁著周末,再來(lái)看看源碼里是如何實(shí)現(xiàn)的。

類(lèi)組件的Props對(duì)比

類(lèi)組件是否需要更新需要實(shí)現(xiàn)shouldComponentUpdate方法,通常講的是如果繼承的是PureComponent則會(huì)有一個(gè)默認(rèn)淺對(duì)比的實(shí)現(xiàn)。

// 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的實(shí)現(xiàn)如上,我以前以為在聲明時(shí)默認(rèn)會(huì)實(shí)現(xiàn)shouldComponentUpdate方法,但實(shí)際上并沒(méi)有一個(gè)默認(rèn)的方法。

接下來(lái)看看shouldComponentUpdate方法的調(diào)用。

// ReactFiberClassComponent.js
function checkShouldComponentUpdate(
  workInProgress,
  ctor,
  oldProps,
  newProps,
  oldState,
  newState,
  nextContext,
) {
  const instance = workInProgress.stateNode;
  // 如果實(shí)利實(shí)現(xiàn)了shouldComponentUpdate則返回調(diào)用它的結(jié)果
  if (typeof instance.shouldComponentUpdate === 'function') {
    const shouldUpdate = instance.shouldComponentUpdate(
      newProps,
      newState,
      nextContext,
    );
    return shouldUpdate;
  }

  // PureReactComponent的時(shí)候進(jìn)行淺對(duì)比
  if (ctor.prototype && ctor.prototype.isPureReactComponent) {
    return (
      !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
    );
  }

  return true;
}

可以看出實(shí)際上并沒(méi)有單獨(dú)寫(xiě)一個(gè)shouldComponentUpdate方法給PureReactComponent,而是在對(duì)比的時(shí)候就返回淺對(duì)比的結(jié)果。

淺對(duì)比的答案都在shallowEqual方法里了。

shallowEqual 淺對(duì)比

// shallowEqual.js
function shallowEqual(objA: mixed, objB: mixed): boolean {
  // 一樣的對(duì)象返回true
  if (Object.is(objA, objB)) {
    return true;
  }

  // 不是對(duì)象或者為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數(shù)量不同返回false
  if (keysA.length !== keysB.length) {
    return false;
  }

  // 對(duì)應(yīng)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方法原理很簡(jiǎn)單了

  1. 先判斷兩者是否為同一對(duì)象。
  2. 判斷兩者的值是否不為object或?yàn)閚ull。
  3. 對(duì)比兩者key的長(zhǎng)度。
  4. 判斷兩者key對(duì)應(yīng)的值是否相同。

原來(lái)原理是這樣簡(jiǎn)單的對(duì)比,如果我面試的時(shí)候能夠口噴源碼,會(huì)不會(huì)工資更高一些呢?

函數(shù)組件的淺對(duì)比

函數(shù)組件的淺對(duì)比方式則使用React.memo方法實(shí)現(xiàn)。

// 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函數(shù)最為第二個(gè)參數(shù)。

內(nèi)部的處理其實(shí)是手動(dòng)創(chuàng)建了一個(gè)$$typeof為REACT_MEMO_TYPE的ReactElement,方便之后的類(lèi)型判斷。

React.memo組件的創(chuàng)建會(huì)稍微復(fù)雜一些,由于可以傳入第二個(gè)自定義的compare函數(shù),所以在內(nèi)部其實(shí)會(huì)被定義為2種類(lèi)型的Fiber節(jié)點(diǎn)。

  • 沒(méi)有傳入compare函數(shù)的為SimpleMemoComponent。
  • 傳入了自定義compare函數(shù)的為MemoComponent。

但是實(shí)際對(duì)于Props的比較都是相同的,默認(rèn)都是調(diào)用shallowEqual方法來(lái)對(duì)比。

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個(gè)組件,我也沒(méi)大看懂,藍(lán)廋香菇,大概是和更新調(diào)度相關(guān)的。

SimpleMemoComponent的Fiber節(jié)點(diǎn)實(shí)際等于改了個(gè)名的函數(shù)組件,走流程會(huì)直接走到函數(shù)組件里,而MemoComponent則是套了一層殼,需要先把殼剝開(kāi)生成子Fiber節(jié)點(diǎn),再由子Fiber節(jié)點(diǎn)的判斷走到函數(shù)組件里。

以上就是Props淺對(duì)比的分析了~

以上就是詳解React中Props的淺對(duì)比的詳細(xì)內(nèi)容,更多關(guān)于React中Props的淺對(duì)比的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React中的合成事件是什么原理

    React中的合成事件是什么原理

    React 中的事件,是對(duì)原生事件的封裝,叫做合成事件。這篇文章主要通過(guò)幾個(gè)簡(jiǎn)單的示例為大家詳細(xì)介紹一下React中的合成事件,感興趣的可以了解一下
    2023-02-02
  • react-router?v6實(shí)現(xiàn)權(quán)限管理+自動(dòng)替換頁(yè)面標(biāo)題的案例

    react-router?v6實(shí)現(xiàn)權(quán)限管理+自動(dòng)替換頁(yè)面標(biāo)題的案例

    這篇文章主要介紹了react-router?v6實(shí)現(xiàn)權(quán)限管理+自動(dòng)替換頁(yè)面標(biāo)題,這次項(xiàng)目是有三種權(quán)限,分別是用戶,商家以及管理員,這次寫(xiě)的權(quán)限管理是高級(jí)權(quán)限能訪問(wèn)低級(jí)權(quán)限的所有頁(yè)面,但是低級(jí)權(quán)限不能訪問(wèn)高級(jí)權(quán)限的頁(yè)面,需要的朋友可以參考下
    2023-05-05
  • React 狀態(tài)的不變性實(shí)例詳解

    React 狀態(tài)的不變性實(shí)例詳解

    這篇文章主要為大家介紹了React 狀態(tài)的不變性實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 圖文示例講解useState與useReducer性能區(qū)別

    圖文示例講解useState與useReducer性能區(qū)別

    這篇文章主要為大家介紹了useState與useReducer性能區(qū)別圖文示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • React中useEffect函數(shù)的使用詳解

    React中useEffect函數(shù)的使用詳解

    useEffect是React中的一個(gè)鉤子函數(shù),用于處理副作用操作,這篇文章主要為大家介紹了React中useEffect函數(shù)的具體用法,希望對(duì)大家有所幫助
    2023-08-08
  • React?Hooks鉤子中API的使用示例分析

    React?Hooks鉤子中API的使用示例分析

    在react類(lèi)組件(class)寫(xiě)法中,有setState和生命周期對(duì)狀態(tài)進(jìn)行管理,但是在函數(shù)組件中不存在這些,故引入hooks(版本:>=16.8),使開(kāi)發(fā)者在非class的情況下使用更多react特性
    2022-08-08
  • React項(xiàng)目中動(dòng)態(tài)插入HTML內(nèi)容的實(shí)現(xiàn)

    React項(xiàng)目中動(dòng)態(tài)插入HTML內(nèi)容的實(shí)現(xiàn)

    本文主要介紹了React項(xiàng)目中動(dòng)態(tài)插入HTML內(nèi)容的實(shí)現(xiàn),通過(guò)使用React的dangerouslySetInnerHTML屬性,我們可以將HTML內(nèi)容插入到組件中,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • 基于React-Dropzone開(kāi)發(fā)上傳組件功能(實(shí)例演示)

    基于React-Dropzone開(kāi)發(fā)上傳組件功能(實(shí)例演示)

    這篇文章主要介紹了基于React-Dropzone開(kāi)發(fā)上傳組件,主要講述的是在React-Flask框架上開(kāi)發(fā)上傳組件的技巧,需要的朋友可以參考下
    2021-08-08
  • react中將html字符串渲染到頁(yè)面的實(shí)現(xiàn)方式

    react中將html字符串渲染到頁(yè)面的實(shí)現(xiàn)方式

    這篇文章主要介紹了react中將html字符串渲染到頁(yè)面的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • React 并發(fā)功能體驗(yàn)(前端的并發(fā)模式)

    React 并發(fā)功能體驗(yàn)(前端的并發(fā)模式)

    React 是由 Facebook 軟件工程師 Jordan Walke 創(chuàng)建,React 的第一個(gè)版本在七年前問(wèn)世,現(xiàn)在,F(xiàn)acebook 負(fù)責(zé)維護(hù),本文給大家介紹React 并發(fā)功能體驗(yàn)前端并發(fā)模式的問(wèn)題,感興趣的朋友跟隨小編一起看看吧
    2021-07-07

最新評(píng)論

调兵山市| 民勤县| 临海市| 桂平市| 宜兴市| 鹤峰县| 都江堰市| 大邑县| 宝鸡市| 抚松县| 探索| 凌源市| 琼海市| 大宁县| 视频| 咸宁市| 开远市| 商丘市| 抚州市| 庆云县| 广饶县| 万盛区| 仁寿县| 淮北市| 马关县| 车致| 北川| 报价| 五莲县| 望奎县| 庄河市| 永吉县| 南昌市| 连云港市| 曲松县| 石柱| 都安| 进贤县| 南雄市| 黄平县| 芜湖县|