Reputation: 457
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?
Upvotes: 4
Views: 10583
Reputation: 558
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
Upvotes: 2
Reputation: 1450
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.
Upvotes: 11