Ultimate React Hooks Guide
Source: Dev.to
Introduction
React Hooks are functions that let you “hook into” React state and lifecycle features from function components. They were introduced in React 16.8. Below is a list of common React hooks, their explanations, and examples of usage. Additionally, this guide covers how to create custom hooks.
1. useState
The useState hook lets you add state to function components.
Explanation
useState returns an array with two elements: the current state value and a function to update it.
Usage
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
You clicked {count} times
setCount(count + 1)}>
Click me
);
}
2. useEffect
The useEffect hook lets you perform side effects in function components.
useEffect With Dependencies
useEffect runs after the first render and after every update. You can also specify dependencies to control when the effect runs.
Usage
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
You clicked {count} times
setCount(count + 1)}>
Click me
);
}
useEffect With an Empty Dependency Array []
Runs only once after the initial render (similar to componentDidMount).
useEffect(() => {
console.log('This runs only once after the first render');
}, []);
Use case: Fetching data when the component mounts, setting up event listeners, etc.
useEffect Without Dependencies
Runs on every render (initial and subsequent re‑renders).
useEffect(() => {
console.log('This runs after every render');
});
Use case: Running code that doesn’t depend on specific state changes, like logging or animations.
Cleanup Function in useEffect
If useEffect returns a function, it acts as a cleanup that runs before the next effect or when the component unmounts.
useEffect(() => {
const interval = setInterval(() => {
console.log('Interval running...');
}, 1000);
return () => {
clearInterval(interval); // Cleanup on unmount
};
}, []);
Use case: Cleaning up event listeners, canceling API calls, clearing intervals, etc.
3. useContext
The useContext hook lets you access the value of a context.
Explanation
useContext accepts a context object (the value returned from React.createContext) and returns the current context value.
Usage
import React, { useContext } from 'react';
const MyContext = React.createContext();
function MyComponent() {
const value = useContext(MyContext);
return {value};
}
function App() {
return (
);
}
4. useReducer
The useReducer hook is an alternative to useState for managing complex state logic.
Explanation
useReducer returns an array with the current state and a dispatch function to trigger state updates.
Usage
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error('Unknown action');
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
Count: {state.count}
dispatch({ type: 'increment' })}>
Increment
dispatch({ type: 'decrement' })}>
Decrement
);
}
5. useCallback
The useCallback hook returns a memoized callback.
Explanation
useCallback returns a memoized version of the callback that only changes if one of the dependencies has changed.
Usage
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, [count]);
return (
You clicked {count} times
Click me
);
}
6. useMemo
The useMemo hook returns a memoized value.
Explanation
useMemo only recomputes the memoized value when one of its dependencies changes.
Usage
import React, { useState, useMemo } from 'react';
function ExpensiveComponent({ value }) {
// Simulate an expensive calculation
const computed = useMemo(() => {
let result = 0;
for (let i = 0; i Result: {computed};
}
Feel free to extend this guide with additional hooks such as useRef, useLayoutEffect, or custom hooks tailored to your project’s needs.
6. useMemo (Additional Example)
function ExpensiveCalculationComponent() {
const [count, setCount] = useState(0);
const [value, setValue] = useState("");
const expensiveCalculation = useMemo(() => {
// Assume this is an expensive calculation
return count * 2;
}, [count]);
return (
Expensive Calculation: {expensiveCalculation}
setCount(count + 1)}>Increment
setValue(e.target.value)} />
);
}
7. useRef
The useRef hook returns a mutable ref object.
Explanation
useRef is useful for accessing DOM elements or persisting values across renders.
Usage
import React, { useRef } from "react";
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
Focus the input
);
}
8. useImperativeHandle
The useImperativeHandle hook customizes the instance value that is exposed when using ref.
Explanation
useImperativeHandle should be used with React.forwardRef.
Usage
import React, { useRef, useImperativeHandle, forwardRef } from "react";
const FancyInput = forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
}));
return ;
});
function Parent() {
const inputRef = useRef();
return (
inputRef.current.focus()}>Focus Input
);
}
9. useLayoutEffect
The useLayoutEffect hook runs after all DOM mutations.
Explanation
useLayoutEffect is similar to useEffect, but it fires synchronously after all DOM mutations.
Usage
import React, { useLayoutEffect, useRef } from "react";
function LayoutEffectComponent() {
const divRef = useRef();
useLayoutEffect(() => {
console.log(divRef.current.getBoundingClientRect());
});
return Hello, world!;
}
10. useDebugValue
The useDebugValue hook is used to display a label for custom hooks in React DevTools.
Explanation
useDebugValue can be helpful for debugging custom hooks.
Usage
import React, { useState, useDebugValue } from "react";
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
useDebugValue(isOnline ? "Online" : "Offline");
// Imagine this is an actual implementation
return isOnline;
}
11. Custom Hooks
Custom hooks let you extract component logic into reusable functions.
Explanation
Custom hooks are normal JavaScript functions that can call other hooks.
Example: useFetch
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
export default useFetch;
Usage of the Custom Hook
import React from "react";
import useFetch from "./useFetch";
function App() {
const { data, loading } = useFetch("https://api.example.com/data");
if (loading) {
return Loading...;
}
return (
{JSON.stringify(data, null, 2)}
);
}
export default App;
This guide provides a comprehensive overview of React hooks, their usage, and how to create custom hooks.