简体   繁体   中英

Why React.Memo() keeps rendering my component

I made an example to get to know more deeply the React.Memo().

I tried to pass a string from the parent to the child . then the component wasn't rendred except the first default rerending.

But When I passed an array from the parent to the child the components get re-render.

So why the component keeps re-render when passing arrays and objects and not re-render when passing string .

Is that related to the reference values and primitive values of javascript ?

here's the code for what was I trying to do.

the parent :

import Child from "./Child";

export default function App() {
  const name = {
    firstName: "Amr"
  };

  return <Child name={name} />;
}

The Child

import React from "react";

const Child = ({ name }) => {
  const name1 = "Amr";

  const name2 = "Amr";

  // console.log(name1 === name2);

  const obj1 = {
    name: "Mohamed"
  };

  const obj2 = {
    name: "Mohamed"
  };

  const arr1 = ["Amr"];

  const arr2 = ["Amr"];

  console.log(arr1 === arr2);

  // console.log(obj1 === obj2); => obj1 => refrence number 1
  // obj2 => refrence number 2
  // 1 === 2;
  // false

  areEqual(name, {
    firstName: "Amr"
  });

  return <h2>{name.firstName}</h2>;
};

// javascript [] {} => refrence value
// javascript '' or anythinng primtive value;

// obj1 = 1, obj2 = 2;
// obj1 === obj2 result false 1 === 2

function areEqual(prevProps, nextPops) {
  if (prevProps === nextPops) {
    console.log("equal");
  } else {
    console.log("not equal");
  }
}

export default React.memo(Child, areEqual);

I used a function also areEqual that returns true or false based on if the prevProps and nextProps are equal or not.

This function already returns for me true when I pass a String and false when I pass an array .

So, am I right or there's something missing.

Thanks

UPDATE:

If what I mentioned is right, so the React.memo() will be useless.

Is that Right?

By default React.memo() does a shallow comparison of props and objects of props - and this is why you were experiencing rerenders when props were of type 'object', because reference recreates on each rerender.

React.memo receives two argument(2nd one is optional), and second one is custom equality function which you can use in order to stabilize rerenders when having props as non primitive values. So, for example, you can do something like this: React.memo(SomeComponent, (prevProps, currentProps) => isDeepEqual(prevProps.someObject, currentProps.someObject)) .

Meaning that React.memo is not useless, it just uses shallow comparison by default, but also offers you posibillity to provide it with custom equality checker which you might wanna use in your example. Either you shall use deep equality check within React.memo, or you shall stabilize props in parent component by wrapping their value with useMemo.

It depends on their parent components some times it is necessary React.memo But in your case, as you said, its reference changes every time you define an array or object. I recommend you to use React.useMemo. For example:

const user = React.useMemo(() => {
    return {
    firstName: "Amr"
  }
}, []); // Second parameter works same as useCallback

React.memo wont re-render the component because user props didn't change

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM