A brief comparison of Props in React

A brief comparison of Props in React

When I went for an interview last week, the interviewer asked me how to compare props in PureComponent . The concept was already memorized in my mind, and the first thing I blurted out was shallow comparison. Then the interviewer asked me how I did the shallow comparison, but I couldn't answer.

Take advantage of the weekend to see how it is implemented in the source code.

Props comparison of class components

Whether the class component needs to be updated needs to implement the shouldComponentUpdate method. Generally speaking, if it inherits PureComponent, there will be a default shallow comparison implementation.

// 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;

The implementation of PureComponent is as above. I used to think that the shouldComponentUpdate method would be implemented by default when declaring it, but in fact there is no default method.

Next, let's look at the call to shouldComponentUpdate method.

// ReactFiberClassComponent.js
function checkShouldComponentUpdate(
  workInProgress,
  ctor,
  oldProps,
  newProps,
  oldState,
  newState,
  nextContext,
) {
  const instance = workInProgress.stateNode;
  // If the instance implements shouldComponentUpdate, return the result of calling it if (typeof instance.shouldComponentUpdate === 'function') {
    const shouldUpdate = instance.shouldComponentUpdate(
      newProps,
      newState,
      nextContext,
    );
    return shouldUpdate;
  }

  // Shallow comparison when using PureReactComponent if (ctor.prototype && ctor.prototype.isPureReactComponent) {
    return (
      !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
    );
  }

  return true;
}

It can be seen that there is actually no separate shouldComponentUpdate method written for PureReactComponent, but the result of shallow comparison is returned during comparison.

The answers to the shallow comparisons are all in the shallowEqual method.

shallowEqual shallow comparison

// shallowEqual.js
function shallowEqual(objA: mixed, objB: mixed): boolean {
  // The same object returns true
  if (Object.is(objA, objB)) {
    return true;
  }

  // If it is not an object or null, return false
  if (
    typeof objA !== 'object' ||
    objA === null ||
    typeof objB !== 'object' ||
    objB === null
  ) {
    return false;
  }

  const keysA = Object.keys(objA);
  const keysB = Object.keys(objB);

  // If the number of keys is different, return false
  if (keysA.length !== keysB.length) {
    return false;
  }

  // If the corresponding key values ​​are not the same, return 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;
}

The principle of shallowEqual method is very simple

  1. First determine whether the two are the same object.
  2. Determine whether the value of both is not an object or is null.
  3. Compare the lengths of the two keys.
  4. Determine whether the values ​​corresponding to the two keys are the same.

It turns out that the principle is such a simple comparison. If I can recite the source code during the interview, will I get a higher salary?

A brief comparison of functional components

The shallow comparison method of function components is implemented using the React.memo method.

// 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 method also supports passing in a compare function as the second parameter.

The internal processing actually manually creates a ReactElement with $$typeof as REACT_MEMO_TYPE to facilitate subsequent type judgment.

The creation of the React.memo component is a little more complicated. Since a second custom compare function can be passed in, it is actually defined as two types of Fiber nodes internally.

  • The one without the compare function passed in is SimpleMemoComponent.
  • The one that passes in the custom compare function is MemoComponent.

However, the actual comparison of Props is the same, and the shallowEqual method is called by default for comparison.

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);
}
// ... 

As for why it is divided into two components, I don’t quite understand it. It is probably related to update scheduling.

The Fiber node of SimpleMemoComponent is actually equivalent to a function component with a changed name. The process will go directly to the function component, while MemoComponent is covered with a shell. You need to peel off the shell first to generate a child Fiber node, and then go to the function component based on the judgment of the child Fiber node.

The above is a brief analysis of Props.

The above is the detailed content of the shallow comparison of Props in React. For more information about the shallow comparison of Props in React, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • React's context and props explained
  • Detailed explanation of the use of props in React's three major attributes
  • Talk about the Render Props pattern in React
  • ES6 class chain inheritance, instantiation and react super (props) principle detailed explanation
  • An article to help you understand the principles of React Props

<<:  Detailed steps for completely uninstalling MySQL 5.7

>>:  Example of how to configure nginx in centos server

Recommend

Mysql join query principle knowledge points

Mysql join query 1. Basic concepts Connect each r...

Using Openlayer in Vue to realize loading animation effect

Note: You cannot use scoped animations! ! ! ! via...

One line of code solves various IE compatibility issues (IE6-IE10)

x-ua-compatible is used to specify the model for ...

Brief analysis of centos 7 mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar

Baidu Cloud Disk: Link: https://pan.baidu.com/s/1...

js to call the network camera and handle common errors

Recently, due to business reasons, I need to acce...

Vue3.0 implements the encapsulation of the drop-down menu

Vue3.0 has been out for a while, and it is necess...

How to move a red rectangle with the mouse in Linux character terminal

Everything is a file! UNIX has already said it. E...

Detailed explanation of how to use Node.js to implement hot reload page

Preface Not long ago, I combined browser-sync+gul...

CSS sample code with search navigation bar

This article shows you how to use CSS to create a...

How to connect Django 2.2 to MySQL database

1. The error information reported when running th...

jQuery implements shopping cart function

This article example shares the specific code of ...

Detailed explanation of using Vue.prototype in Vue

Table of contents 1. Basic Example 2. Set the sco...

JavaScript to achieve elastic navigation effect

This article shares the specific code for JavaScr...

js canvas realizes circular water animation

This article example shares the specific code of ...