ShaharAmir
← Back to Blog
React2 min read

React Custom Hooks Patterns

Stop repeating yourself. Extract logic into reusable hooks

S
Shahar Amir

The Pattern

Custom hooks are functions that use other hooks. They start with use.

useLocalStorage

javascript
123456789101112131415
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
// Usage
const [theme, setTheme] = useLocalStorage('theme', 'dark');

useDebounce

javascript
1234567891011121314151617
function useDebounce(value, delay = 500) {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebounced(value);
}, delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debounced;
}
// Usage
const [search, setSearch] = useState('');
const debouncedSearch = useDebounce(search, 300);

useToggle

javascript
123456789101112
function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = useCallback(() => {
setValue(v => !v);
}, []);
return [value, toggle];
}
// Usage
const [isOpen, toggleOpen] = useToggle();

useFetch

javascript
123456789101112131415161718
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, [url]);
return { data, loading, error };
}
// Usage
const { data, loading } = useFetch('/api/users');

Rules

  1. Name starts with use
  2. Can call other hooks
  3. Must follow hook rules (top level, same order)

Extract. Reuse. Ship faster.

#hooks#patterns#reusable#clean-code

Stay Updated 📬

Get the latest tips and tutorials delivered to your inbox. No spam, unsubscribe anytime.