DEV Community

Cover image for Let's talk React - How to use a Custom Hook multiple times
Clément Creusat
Clément Creusat

Posted on

Let's talk React - How to use a Custom Hook multiple times

Making a custom hook real quick..

Example with a useCounter hook where we extract the logic to reuse it.

  • a state equal to the argument score or 0 if we do not pass one.
  • a method to increment number: +1
  • a method to decrement number: -1
  • returning count state and our two methods has an object.
export const useCounter = (score: number) => {
  const [count, setCount] = useState(score || 0);
  const increment = useCallback(() => setCount(count + 1), [count]);
  const decrement = useCallback(() => setCount(count - 1), [count]);
  return { count, increment, decrement };
};
Enter fullscreen mode Exit fullscreen mode

Using your useCounter hook

with a variable

In React's documentation, you will read the approach to call your custom hook.

Storing the useCounter hook inside a variable using const.

const counter = useCounter(0);

So inside your component:

const counter = useCounter(0);
// Display your dynamic attribute starting from 0.
<p> {counter} </p>
// Using useCounter methods to add or remove 1
<button onClick={counter.increment}>Increment</button>
<button onClick={counter.decrement}>Decrement</button>
Enter fullscreen mode Exit fullscreen mode

with destructuring

Remember that we returned an object ?

{ count, increment, decrement }

So inside your component:

const { count, increment, decrement } = useCounter(0);
// Display your dynamic attribute starting from 0.
<p> {count} </p>
// Using useCounter methods to add or remove 1
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
Enter fullscreen mode Exit fullscreen mode

This is great. Now, we know how to use the custom hook we created but this is not helpful to use it a bunch of times if needed...

How to use your useCounter hook multiple times?

Let's see the part to use your useCounter hook multiple times in the same component.

with multiple variables

So to use it more than once inside a component, you will do this :

const counter = useCounter(0);
const secondCounter = useCounter(0);

<p>{counter}</p>
<p>{secondCounter}</p>
Enter fullscreen mode Exit fullscreen mode

Every counter has his own local state and will not interfere with the others.

with destructuring

We just saw that we can destructure an object and we know something else : it is possible to rename our properties / variables when destructuring.

const { count: firstCount, increment: firstIncrement, decrement: firstDecrement, } = useCounter(0);
const { count: secondCount, increment: secondIncrement, decrement: secondDecrement } = useCounter(0);

<p>{firstCount}</p>
<p>{secondCount}</p>
Enter fullscreen mode Exit fullscreen mode

Same as above, every counter has his own local state and will not interfere with the others.

You can check a live example right there : StackBlitz Example

What if returning an Array inside your custom hook?

When creating the custom hook, we return count, increment and decrement as an object.

Let see how to use it if returning an array:

[ count, increment, decrement ]

One time in a component

Calling it only once inside a component would be:

const [count, increment, decrement] = useCounter(0);

<p> {count} </p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
Enter fullscreen mode Exit fullscreen mode

Multiple times

We also use destructuring with array an directly renaming each one.


const [counter, incrementCounter, decrementCounter] = useCounter(0);
  const [secondCounter, secondIncrementCounter, secondDecrementCounter] =
    useCounter(0);

<p> {counter} </p>
<button onClick={incrementCounter}>Increment</button>
<button onClick={decrementCounter}>Decrement</button>

<p> {secondCounter} </p>
<button onClick={secondIncrementCounter}>Increment</button>
<button onClick={secondDecrementCounter}>Decrement</button>
Enter fullscreen mode Exit fullscreen mode

You can check a live example right there : StackBlitz Example

Hope this article will help and Let's Talk React soon!

Discussion (4)

Collapse
link2twenty profile image
Andrew Bone

Nice introductory article into custom hooks and destructing. This example would benefit from using useReducer rather than useState. I think you can learn all the same lessons (though we'd use an array rather than an object) and the end product would be more powerful while using less memory.

I did a quick example 😊

Collapse
ccreusat profile image
Clément Creusat Author

You're totally right. If a custom hook is more complex, we definitely need to re-think it with useReducer.
Here we have a state and two methods (three with your example and the reset method).. but if the custom hook has x methods better to switch to the useReducer approach.

Collapse
andrewbaisden profile image
Andrew Baisden

Great tutorial its definitely going to be valuable for React developers veteran and beginner alike.

Collapse
mp3846 profile image
Mostafa Pourmorad • Edited on

Great!
What about a custom hook which doesn't return anything?
For example a useShortcutKeys hook for passing a callback after user pressed some key combinations
I have tried to use it two times in a component but the second one overrides first one!