DEV Community

Cover image for Use previous value through a React hook
Robin van der Vleuten
Robin van der Vleuten

Posted on • Originally published at robinvdvleuten.nl

Use previous value through a React hook

React Hooks were definitely a game changer when they got introduced in React v16.8.0. It took me some time to familiarize myself with their usage. But now that I have used them a lot, I can see how using them make React components easier to reason about and maintain.
By creating custom hooks that you reuse within components, you can break up complex logic to smaller understandable functions.

After developing many applications, I have gathered a library of React hook patterns used in almost any of these projects.

One of them is retrieving the previous value of the state for example. Written within a handful lines of code, it makes clever use of the useRef() hook. As I found out that not only you can use this hook to store the reference to a HTML element, but that it stores any value you pass it.
When combined with the useEffect() hook, you can create a small helper to store and retrieve the previous value of the variable you passed to it.

Let me show you the usePrevious() hook.

import React from 'react';

export default function usePrevious<T>(value: T): T {
  // Create a reference to hold the previous version of the value,
  // as it is basically a generic object whose `current` property can hold any value.
  const ref = React.useRef<T>();

  // Use the `useEffect` hook to run a callback...
  React.useEffect(() => {
    // ...to store the passed value on the ref's current property...
    ref.current = value;
  }, [value]); // ...whenever the value changes.

  // And return the currently stored value,
  // as this will run before the `useEffect` callback runs.
  return ref.current;
}
Enter fullscreen mode Exit fullscreen mode

What to do with this hook?

When you combine the usePrevious hook with useState, you can run a callback whenever a value differs from the previous render cycle. I mainly use it in applications to compare boolean variables to their previous values, like the following.

import React from 'react';

const Application = () => {
  // Call some external API through a custom hook.
  const { data, loading } = useAsyncApi()
  // Pass its loading indicator to our created hook.
  const wasLoading = usePrevious<boolean>(loading);

  // Use the `useEffect` hook to run a callback...
  React.useEffect(() => {
    // ...to check if the API was loading but now it is completed...
    if (!loading && wasLoading) {
        // ...and run some arbitary code...
    }
  }, [loading, wasLoading]); // ...whenever one of these changes.

  return (
    <div>
      {/* ... */}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

How will you use this hook in your applications? Let me know, as I am curious to find out any other use case you can come up with!

Latest comments (2)

Collapse
 
snigo profile image
Igor Snitkin

The fact that useEffect is called after render (return) doesn't mean anything to your Application component, I hope you realise this. Any component update, apart from loading, will update wasLoading value. And then when loading will eventually change, the fact that useEffect is called after render will play cruel joke with you, because your if statement will never fire. Hmm...

Collapse
 
snigo profile image
Igor Snitkin

...though I guess in this will still work based on the fact that useEffect in custom hook will always be invoked before the one in Application, just in time switching values back. OK