Hooks
Hooks let use state and other features in a functional react component. You might have come across at least a few of them for eg. useState, useEffect, useCallback etc. In this blog post will try to make our own custom hook and use it our react?
Custom Hook
A Custom Hook is a JavaScript function whose name starts with ”use” and that may call other Hooks. There are 3 major rules of the hook to be followed as below
- Hook should be called inside React Component or Hooks.
- Hooks should be called at the top level of the component or hook, nesting of hooks is not permitted.
- The name of the hook should start with the word "use" in lowercase.
Problem
We have a small counter application, which has a count state, increment button, and a decrement button to update the count state. We would like to implement a functionality that saves the count to the local storage so it's not lost on reload/refresh of the page
Solution
1) let's start by implementing the above solution using useState & useEffect hook
import React from "react";
export default function App() {
let [count, setCount] = React.useState( localStorage.getItem('count') || 0);
React.useEffect(() => {
localStorage.setItem('count', count);
}, [count]);
return (
<div className="App">
<button onClick={() => { setCount(count - 1) }}>
Decrement
</button>
 
{count}
 
<button onClick={() => { setCount(count + 1) }}>
Increment
</button>
</div>
);
}
2) Let's create a custom hook useSyncStateToLocalStorage to combine both the useState hook and useEffect hook usage from the above example in a single useSyncStateToLocalStorage hook
import React from "react";
export default function App() {
let [count, setCount] = useSyncStateToLocalStorage();
return (
<div className="App">
<button onClick={() => { setCount(count - 1) }}>
Decrement
</button>
 
{count}
 
<button onClick={() => { setCount(count + 1) }}>
Increment
</button>
</div>
);
}
function useSyncStateToLocalStorage(){
let [count, setCount] = React.useState( localStorage.getItem('count') || 0);
React.useEffect(() => {
localStorage.setItem('count', count);
}, [count]);
return [count, setCount];
}
3) But our useSyncStateToLocalStorage custom hook is tied to the count state, let's make it reusable, by adding a key argument and initialState argument
function useSyncStateToLocalStorage(key, initialState){
let [value, setValue] = React.useState( localStorage.getItem(key) || initialState);
React.useEffect(() => {
localStorage.setItem(key, value);
}, [key, value]);
return [value, setValue];
}
4) Let's use or modified hook in our application
let [count, setCount] = useSyncStateToLocalStorage('count', 0);
To Summarize
- Custom hooks are nothing but functions and their name starts with the 'use' keyword.
- Hooks or Custom hooks should be called inside a react component or other hooks only.
- Hooks should be called at the top level of the component or hook.
- Nesting of hooks is not allowed.