1

I'm trying to reduce unnecessary rendering in child components. When a child component trigger a state modification all others unaffected components get re-rendered (in virtual DOM of course). I'm using React.memo but if I let the comparison to React.memo the renders are the same as if I wasn't using it.

To investigate the problem I tried to console.log the props.

The first component render a list of components based on props and on a template from another file.

const List = props => { return ( <div id="List"> {template[props.status].map( el => <ListItem activeClass={props.active === el.type ? 'active' : ''} handleClick={props.handleClick} key={el.type} itemType={el.type} text={el.text} /> ) } </div> ) } 

I'm starting using memo in the ListItem component

 const ListItem = React.memo( props => { return ( <button className={props.activeClass} onClick={props.handleClick} title={props.itemType} value={props.itemType} > {props.text} </button> ) }, (prevProps, nextProps) => { prevProps === nextProps }; 

Whit this I get the same renders as if I wasn't using React.memo, so I console.log every single props.

prevProps === nextProps //false prevProps.itemType === nextProps.itemType //true prevProps.text === nextProps.text //true prevProps.handleClick === nextProps.handleClick //true prevProps.activeClass === nextProps.activeClass //true 

handleClick is from an hook and I used useCallback to get always the same reference, I don't have other props so I don't know why

prevProps === nextProps 

is still false. This happens in others child components, so I don't want to add a custom function in every one of them, what should I check next to ensure that prevProps === nextProps is true?

4 Answers 4

5

If you use === JS will make a reference comparison and what you need is a deep comparison. For do this you could use something like this => https://stackoverflow.com/a/38416465/8548193

or use lodash [https://lodash.com/docs/] to make it more easier;

with lodash it will be something like this:

const _ = require("lodash"); _.isEqual(prevProps, nextProps); 
Sign up to request clarification or add additional context in comments.

4 Comments

Do you mean that even if the objects are identical, React.memo alone can't be used for this kind of optimization? I added the function with === because React.memo alone wasn't working as I would it to work.
yes, because what the React.memo only make a shallow compare: reactjs.org/docs/react-api.html#reactmemo
yes, maybe I misunderstood the meaning of shallow compare, I thought that it will check if every value of every key was the same, but reading now on other answers it seems that checks if the references are the same, so is it possible that when the props are passed down nextProps have different references?
I tried using this with an object but it does not seem to deetect the change
0

use JSON.stringify(prevProps) === JSON.stringify(nextProps)

Comments

0

This code:

 }, (prevProps, nextProps) => { prevProps === nextProps }; 

is not quite right. It works if you leave out the {}. Otherwise, it should be

}, (prevProps, nextProps) => { return prevProps === nextProps }; 

Comments

0

i would suggest to convert it into the JSON rather than checking for the reference (===). example :-

JSON.stringify(prevProps) === JSON.stringify(nextProps) or JSON.stringify(prevProps.itemType) === JSON.stringify(nextProps.itemType) || JSON.stringify(prevProps.text) === JSON.stringify(nextProps.text) || JSON.stringify(prevProps.handleClick) === JSON.stringify(nextProps.handleClick) || JSON.stringify(prevProps.activeClass) === JSON.stringify(nextProps.activeClass); 

converting to JSON will check the data inside the props and will check if both strings are same or not.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.