How to avoiding "options" props from being initialised inline?

Viewed 135

Since the reference of options changes when ParentComp re-renders, what are some good methods to prevent SubComp rerendering when its props haven't changed? Example situation:

const ParentComp = ({ uri, someOtherProp }) => {
  [...some other state hooks here]
  return <SubComp options={{ uri }} someOtherProp={someOtherProp}/>
}
2 Answers

React.memo

If your function component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.

const ParentComp = ({ uri, someOtherProp }) => {
  [...some other state hooks here]
  return <SubComp options={{ uri }} someOtherProp={someOtherProp}/>
}

const equalProps = (prevProps, nextProps) => {
  /*
  return true if passing next props would/should
  result in the same output, false otherwise
  */
};

export default memo(ParentComp, equalProps);

NOTE:

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

Another way of doing this to prevent the parent from passing a new reference for the options prop every time it renders. Now you are doing options={{ uri }} but { uri }!=={ uri }. You are creating a new object for options even if uri didn't change.

You could use useMemo for this

const ParentComp = ({ uri, someOtherProp }) => {
  const options = React.useMemo(() => ({ uri }), [uri]);
  return (
    <SubComp
      options={options}
      someOtherProp={someOtherProp}
    />
  );
};

If you have lots of props and just want SubComponent to re render when something changes you can do the following:

const ParentComp = ({ uri, someOtherProp }) => {
  const memoProps = React.useMemo(
    () => ({
      options: { uri },
      someOtherProp,
    }),
    [someOtherProp, uri]
  );
  return <SubComp {...memoProps} />;
};

This is assuming that SubComp is a either a class that inherits from PureComponent, component wrapped with React Redux connect or a functional component wrapped with React.memo (no need for the compare function). Normal functional components will re render even if props have same reference as previous render.

Related