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.