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
or0
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 };
};
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>
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>
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>
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>
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>
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>
You can check a live example right there : StackBlitz Example
Hope this article will help and Let's Talk React soon!
Top comments (4)
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 😊
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.
Great tutorial its definitely going to be valuable for React developers veteran and beginner alike.
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!