Rendering in React - the devil is in the details...

Just some important takeaways I’ve learned about React rendering when optimizing for performance. We know that a React component will render when its state or props change, but:

  • A render does not mean a commit/write to DOM
  • Renders are usually cheap. You should not strive to prevent every excess render, just expensive ones.
  • Renders are determined by a shallow comparison between the old and new state/props objects. If a component’s props or state contains a non-primative like an object, function, array, etc it will re-render all the time since the new prop values are compared to the old prop values by reference. You can memo a non-primitive prop to try and reduce renders.
  • A parent component rendering will cause its entire children subtree to re-render even if the props and state of the children are the same
    • Memo can be used to avoid children re-renders
    • Using { props.children } also prevents re-rendering if children haven’t changed
  • Because of this, any state update to a parent component that renders a context provider will cause all of its descendants to re-render anyway, regardless of whether they read the context value or not
  • The component under a context provider should probably be memo-ed
  • You can get a similar performance profile to Redux using React context by using the state reducer pattern and memo-ing the child components.

Related links