Custom React Hooks

Introduction
React hooks like useState
and useEffect
are great, but you often find yourself repeating the same logic across different components. That’s where custom hooks come in.
Custom hooks are regular JavaScript functions that start with the word use and can call other hooks inside them. They help you extract logic out of components and reuse it anywhere.
Let’s look at two examples and the steps to create them.
Steps to Create a Custom Hook
- Identify repeated logic
Find parts of your components where you're reusing the sameuseState
,useEffect
, or other hook-based logic. - Create a new file and function
Name your function starting withuse
, likeuseTimer
oruseLocalStorage
. - Move the hook logic into that function
Copy the logic from your component to the new function, and return whatever values or functions the component needs. - Use the hook in your components
Import the custom hook and use it just like a built-in hook.
Example 1: useLocalStorage
Hook
This hook makes it easy to save and load values from localStorage
. Live demo here
Step 1: Create the hook
import { useState } from 'react';
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const saved = localStorage.getItem(key);
return saved !== null ? JSON.parse(saved) : initialValue;
});
const setStoredValue = (newValue) => {
setValue(newValue);
localStorage.setItem(key, JSON.stringify(newValue));
};
return [value, setStoredValue];
}
export default useLocalStorage;
Step 2: Use it in a component
import useLocalStorage from './useLocalStorage';
function App() {
const [name, setName] = useLocalStorage('name', '');
return (
<div>
<input value={name} onChange={(e) => setName(e.target.value)} />
<p>Hello, {name}</p>
</div>
);
}
Example 2: useTimer
Hook
This hook counts up every second and can be used for stopwatches, timers, etc. Live demo here
Step 1: Create the hook
import { useState, useEffect } from 'react';
function useTimer(start = 0) {
const [seconds, setSeconds] = useState(start);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return seconds;
}
export default useTimer;
Step 2: Use it in a component
import useTimer from './useTimer';
function TimerDisplay() {
const seconds = useTimer();
return (
<div>
<h1>Timer</h1>
<p>{seconds} seconds passed</p>
</div>
);
}
Summary
You can build your own custom hooks whenever you notice repeated hook logic. Start small and keep your functions focused.