admin管理员组

文章数量:1391934

I'm trying to reduce unnecessary rendering in child ponents. When a child ponent trigger a state modification all others unaffected ponents get re-rendered (in virtual DOM of course). I'm using React.memo but if I let the parison 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 ponent render a list of ponents 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 ponent

    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 ponents, 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?

I'm trying to reduce unnecessary rendering in child ponents. When a child ponent trigger a state modification all others unaffected ponents get re-rendered (in virtual DOM of course). I'm using React.memo but if I let the parison 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 ponent render a list of ponents 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 ponent

    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 ponents, 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?

Share Improve this question asked Jun 12, 2019 at 15:35 AskaNor_29AskaNor_29 971 silver badge13 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

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

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

with lodash it will be something like this:

const _ = require("lodash");

_.isEqual(prevProps, nextProps);

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

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

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.

本文标签: javascriptReactmemo prevProps always different from nextProps even if props never changesStack Overflow