'Is there a default function I could use for comparisons with React.memo?

I have a <Track/> component that have an object as prop; like

const myData = {
   "location"      : ["http://example.com/1.ogg", "http://example.com/2.mp3"],
   "identifier"    : ["http://example.com/1/", "http://example.com/2/"],
   "title"         : "Track title",
   "creator"       : "Artist name",
   "annotation"    : "Some text",
   "info"          : "http://example.com/",
   "image"         : "http://example.com/",
   "album"         : "Album name",
   "trackNum"      : 1,
   "duration"      : 0,
   "link"          : [
     {"http://example.com/rel/1/" : "http://example.com/body/1/"},
     {"http://example.com/rel/2/" : "http://example.com/body/2/"}
   ],
   "meta"          : [
     {"http://example.com/rel/1/" : "my meta 14"},
     {"http://example.com/rel/2/" : "345"}
   ],
   "extension"     : {
     "http://example.com/app/1/" : [ARBITRARY_EXTENSION_BODY, ARBITRARY_EXTENSION_BODY],
     "http://example.com/app/2/" : [ARBITRARY_EXTENSION_BODY]
   }
 }

Used in

<Track track={myData} onClick={handleClick}/>

When I update myData, I create a new object, which makes React re-render my component, even if its props have equal values.

I've looked at React.memo, which could help to avoid re-rendering with a custom function, like

export default React.memo(Track,isEqualTrack);

Where I would JSON.stringify() to check my data for equality :

function isEqualProp(key,prev,next){
  switch(key){
    case 'track':
      return (JSON.stringify(prev)===JSON.stringify(next))
    break;
  }
}

function isEqualTrack(prevTrackProps, nextTrackProps) {

  const props = Object.keys(nextTrackProps);

  //find the first prop that has changed
  const changedProp = props.find(function(prop){
    const prevValue = prevTrackProps[prop];
    const nextValue = nextTrackProps[prop];
    return !isEqualProp(prop,prevValue,nextValue);
  })

  if (changedProp){
    return false;
  }

  return true;

}

But I would need a default function to compare the props I don't want a special check on.

function isEqualProp(key,prev,next){
  switch(key){
    case 'track':
      return (JSON.stringify(prev)===JSON.stringify(next))
    break;
    default:
      //I NEED A DEFAULT FUNCTION HERE
  }
}

Does that exists ? Or do you have another solution to not re-render my component ? As you see, the data is nested so I can't split it into several "simple" props.

Thanjs a lot !!!



Solution 1:[1]

From https://reactjs.org/docs/react-api.html#reactmemo

This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs.

You should use useMemo to avoid creating a new reference for your myData object instead. That way react's built in shallow comparison would be enough

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sebastian Cruz