DEV Community

Hunter Chang
Hunter Chang

Posted on • Edited on • Originally published at codebushi.com

React Optimizations with React.memo, useCallback, and useReducer.

This post was originally published at codebushi.com

With the recent release of React Hooks, I've switched over to using more and more functional components in my React code. While reading the React docs, I kept seeing mentions of useReducer being "more performant" than useState. I was unclear on why so I did a deep dive into the topic. After much research and experimentation, these are my findings.

It's pretty hard to demonstrate these concepts without a video, but hopefully this content makes sense. I recommend using the React Dev Tools and turning on Highlight Updates in the settings to test things out. It's also helpful to put a console.log on the Child component, if you see the console log, then it's being re-rendered.

===

Our Scenario: A Parent component with a Child component that receives props from the Parent. Assume that both are functional components and the Parent is using useState to manage state.

If the props being passed to the Child component are simple, the Child should be wrapped with React.memo to prevent re-renders if the props don't change. React.memo will automatically optimize the functional component and acts like the shouldComponentUpdate lifecycle method. Read more about React.memo.

If the Parent component is passing a function (specifically, a function that updates the state of the Parent) down to the Child component, only using React.memo will not work. The function in the Parent component will need to be wrapped with the useCallback hook. This is because the function will be "re-rendered" every time the Parent re-renders, so the Child will always consider that function a new prop. Read more about useCallback.

If the useReducer hook is used in the Parent component to manage state, then we won't have to worry about useCallback. useReducer will return a dispatch method that can be passed down to the Child component. The dispatch method won't be "re-rendered" every time the Parent re-renders. I'm pretty sure this is what makes useReducer "more performant" than useState. Read more about useReducer.

When working with deeply nested Child components, it is recommended to use the useReducer hook in conjunction with React Context. You can pass the dispatch method down the tree with Context, which prevents prop drilling. Read more about this pattern.

Top comments (0)