Introduction
React Hooks are one of the most important advancements in React, simplifying state management and enabling functional components to be just as powerful as class components. They address several challenges faced in previous versions of React and have become the standard for modern React development.
What Are React Hooks?
React Hooks are functions that let you use React features (like state and lifecycle methods) in functional components. They enable cleaner, simpler, and more readable code.
Why Were Hooks Introduced?
React Hooks solve several issues present with class components:
Complexity of Classes:
Managing lifecycle and state with this in class components was often error-prone. Hooks simplify this.Logic Reusability:
Hooks make it easier to reuse logic across components without using HOCs or render props.Improved Code Readability:
Hooks streamline component code, making it shorter and easier to understand.Incremental Adoption:
Hooks can be used alongside class components, allowing gradual migration.
Principle React Hooks
React provides several hooks. Let’s explore each with examples and detailed explanations.
1. useState
Manages state in functional components.
Example:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // Initialize state
return (
<div>
<p>Current Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
Explanation:
useState initializes the state variable count to 0.
setCount updates the state.
2. useEffect
Handles side effects like fetching data or updating the DOM.
Example:
import React, { useState, useEffect } from 'react';
function Timer() {
const [time, setTime] = useState(0);
useEffect(() => {
const interval = setInterval(() => setTime(t => t + 1), 1000);
return () => clearInterval(interval); // Cleanup on unmount
}, []); // Run once on mount
return <p>Elapsed Time: {time}s</p>;
}
export default Timer;
Explanation:
Runs the effect once when the component mounts due to an empty dependency array [].
Cleans up the interval on unmount.
3. useContext
Accesses context values.
Example:
import React, { useContext, createContext } from 'react';
const ThemeContext = createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>I am {theme} themed</button>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}
export default App;
Explanation:
- useContext fetches the value from the nearest ThemeContext.Provider
4. useReducer
Manages complex state logic.
Example:
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 type');
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
}
export default Counter;
Explanation:
- useReducer manages complex state transitions with actions.
5. useRef
Persists values or references DOM nodes.
Example:
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef();
const focus = () => inputRef.current.focus();
return (
<div>
<input ref={inputRef} placeholder="Click button to focus" />
<button onClick={focus}>Focus Input</button>
</div>
);
}
export default FocusInput;
Explanation:
- The ref persists across renders and provides a reference to the DOM element.
6. useMemo
Memoizes expensive computations.
Example:
import React, { useMemo } from 'react';
function Factorial({ number }) {
const factorial = useMemo(() => {
const calculateFactorial = n => (n <= 1 ? 1 : n * calculateFactorial(n - 1));
return calculateFactorial(number);
}, [number]);
return <p>Factorial of {number}: {factorial}</p>;
}
export default Factorial;
Explanation:
- useMemo avoids recalculating the factorial unless number changes.
7. useCallback
Memoizes a function.
Example:
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount(prev => prev + 1), []);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
export default Counter;
Explanation:
Prevents unnecessary re-creation of increment on re-renders.
8. useLayoutEffect
Runs synchronously after DOM mutations (before painting).
Example:
import React, { useState, useLayoutEffect, useRef } from 'react';
function Box() {
const boxRef = useRef();
const [color, setColor] = useState('blue');
useLayoutEffect(() => {
console.log('Box dimensions:', boxRef.current.getBoundingClientRect());
}, [color]);
return (
<div>
<div ref={boxRef} style={{ width: 100, height: 100, background: color }}></div>
<button onClick={() => setColor(color === 'blue' ? 'red' : 'blue')}>Toggle Color</button>
</div>
);
}
export default Box;
Explanation:
- useLayoutEffect ensures the DOM is measured before the browser paints.
Conclusion
React Hooks simplify component logic, promote code reusability, and enhance developer productivity. By understanding and effectively using hooks, you can write cleaner, more performant React applications.
Master these hooks, and you’ll unlock the full potential of React!
Top comments (4)
Thanks to the new compiler in the new version (19) of React we will not use useMemo and UseCallback anymore. In short, React 19 doesn't completely eliminate the need for memo , useMemo and useCallback , but it reduces their necessity
Thanks for pointing that out! You're right—React 19's new compiler reduces the need for useMemo and useCallback in many cases by handling re-renders more efficiently. That said, these hooks still have their uses, like optimizing expensive computations or memoizing functions in performance-critical scenarios.
short and precise
well explained!