React Hooks: useReducer, useCallback, & useMemo

Looking for a great (remote only) React Dev? Or just feel like having a chat? Visit my profile on LinkedIn and say hi! 😃

React: Additional Hooks
React: Additional Hooks

Welcome to my new series on React Hooks. Over the next couple of articles, we’ll be going over Reacts Additional Hooks (not and )

useReducer

draws it’s inspiration from Redux’s reducer pattern.

takes three positional arguments — a reducer, its initial state, and a function that can return the initial state — let’s call it for now. The final argument is optional. You can just pass in the as is (e.g. ), but if you want to operate on it in any way, I’d suggest using the function.

The function will automatically receive as an argument.

returns and a function. You can pass the function down to other components which should call it with a . Calling the property is just a naming convention, but most people use it.

This is then caught by the .

If the reducer just returns the current state unchanged, React will not execute a re-render.

When Should We Employ useReducer

is best used when you are dealing with a complex object where individual properties need to be operated on.

For example, if your app pulls in a complex data object like this, and you need to update different properties within it, you should use .

useCallback

stops a function from being re-initialized if a specified dependency hasn’t changed. It is mostly used in conjunction with , where a child component takes the function as a prop.

The function (defined in the parent) will be reinitialized on every render of the parent component if it is not memoized, and as a consequence, will see it as if the prop has changed and will in turn re-render the child component. This causes unnecessary re-renders, which may be quite expensive, depending on the complexity of the component.

Here is an example of an unnecessary re-render caused by a non-memoized function that is a prop:

If you run this code, you’ll notice that the statement gets executed every time you click on the button. This shows us that the component is getting re-rendered every time, which is completely unnecessary.

In this example case, it quite cheap so the optimization is likely excessive, but what if that component was more expensive to re-render? What if there were many such components? Then you’d have a potentially significant slowdown in the app!

So how do we solve this conundrum?

The solution is that we use on the component, but only avoids a re-render if its props haven’t changed.

Since keeps getting re-initialized in the parent, the prop will look different to , so it will re-render. But if we use on , then it will ONLY re-initialize the function if the specified dependencies change.

Here is a complete code example. The way you can tell that is not re-rendering is that the statement doesn’t execute every time you click the button now.

A HUGE thanks to Ben Awad for explaining much of the above in his fantastic video.

useMemo

is similar to except that instead of memoizing a function, it memoizes a value.

Imagine we have to process some data that we receive from an API that does not change between renders. In our example blow, we’ll just mock the data for simplicity sake.

In the example above, every time we click the button, the parent component re-renders, which you can see via the statement, and the function which processes the data is run again — which you can also see via it’s own statement.

Like we said in the section, this could become quite expensive if the function itself is significantly complex enough, or if there are many such processing steps at multiple places in the app.

Since the data doesn’t change between renders, the output of the processing function will not change, so there’s not point in repeating it every single time.

This is where we use , which will save the value to the cache, and will NOT run again during re-renders unless the value of is changed.

If you run the above code, you will see that every time you click on the button, the parent will re-render, but now you’ll see that does not execute on each click (no statement is getting executed), because its output has been memoized until gets changed.

Conclusion

React’s additional hooks enable you to vastly improve the performance of your app by avoiding unnecessary re-renders, and also by avoiding pointlessly running expensive functions whose output will always be the same multiple times.

They also give you an easier way to work with complex objects in your state.

Happy Coding! 😃

I’m a Front End Engineer who loves React, NextJS, and GraphQL. Need a REMOTE React Developer? Contact me at: https://www.linkedin.com/in/bengrunfeld/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store