React Hooks provide a more elegant way to manage state, handle side effects, and reuse logic in functional components. This guide walks you through all the core hooks in React, with detailed explanations and code examples, making it easy to understand their purpose and usage.
What Are React Hooks?
React Hooks are functions that let you “hook into” React’s state and lifecycle features within functional components. Before hooks, these features were only available in class components, but hooks now allow you to write cleaner and more maintainable functional components.
React Hooks
1. useState Hook
The useState
hook lets you add state to functional components. It’s used when you need to keep track of data that changes over time, such as form inputs, counters, etc.
Syntax:
const [state, setState] = useState(initialState);
Example:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
How it Works:
useState
takes the initial state (e.g.,0
) and returns an array with two elements: the current state (count
) and a function to update it (setCount
).- Each time the state changes (e.g., when the button is clicked), the component re-renders with the new state.
2. useEffect Hook
The useEffect
hook is used to handle side effects like data fetching, subscriptions, or directly interacting with the DOM. It replaces lifecycle methods such as componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Syntax:
useEffect(() => {
// Side effect logic
return () => {
// Cleanup (optional)
};
}, [dependencies]);
Example:
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json())
.then(json => setData(json));
}, []); // Empty dependency array means this effect runs only once (on mount)
return (
<div>
{data ? data.map(post => <p key={post.id}>{post.title}</p>) : 'Loading...'}
</div>
);
}
How it Works:
useEffect
accepts a function that runs after the component renders.- The second argument is a dependency array. If any value inside this array changes, the effect will re-run.
- Passing an empty array (
[]
) ensures the effect runs only once, mimickingcomponentDidMount
.
3. useContext Hook
useContext
provides a way to access values from a context without needing to wrap your component with a Consumer
. It allows you to share values like global state across multiple components.
Syntax:
const value = useContext(MyContext);
Example:
import React, { useContext } from 'react';
const UserContext = React.createContext();
function DisplayUserName() {
const user = useContext(UserContext);
return <div>Username: {user}</div>;
}
function App() {
return (
<UserContext.Provider value="JohnDoe">
<DisplayUserName />
</UserContext.Provider>
);
}
How it Works:
useContext
allows you to consume the context directly without needing theConsumer
component.- This is a simple and effective way to manage global data like user info or theme settings.
4. useReducer Hook
The useReducer
hook is used for more complex state management when useState
is not sufficient. It’s an alternative to useState
when you have complex state logic or the next state depends on the previous one.
Syntax:
const [state, dispatch] = useReducer(reducer, initialState);
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:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
How it Works:
useReducer
takes a reducer function and an initial state.- The reducer function handles the logic based on the dispatched action type. This makes it useful for managing complex state logic (e.g., multiple states or state changes dependent on other actions).
5. useMemo Hook
The useMemo
hook is used to memoize expensive computations, so they’re only recalculated when necessary. This is useful for optimizing performance by skipping unnecessary calculations.
Syntax:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Example:
import React, { useState, useMemo } from 'react';
function ExpensiveCalculation({ num }) {
const calculate = (n) => {
console.log("Calculating...");
return n * 2;
};
const result = useMemo(() => calculate(num), [num]);
return <div>Result: {result}</div>;
}
How it Works:
useMemo
memoizes the result of the calculation and only recalculates when one of the dependencies (e.g.,num
) changes.- This improves performance by preventing expensive calculations on every render.
6. useCallback Hook
Similar to useMemo
, the useCallback
hook memoizes functions. It’s particularly useful when you want to avoid unnecessary re-renders by ensuring that a function reference remains the same across renders.
Syntax:
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
Example:
import React, { useState, useCallback } from 'react';
function Button({ onClick, label }) {
return <button onClick={onClick}>{label}</button>;
}
function App() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<Button onClick={handleClick} label="Increment" />
</div>
);
}
How it Works:
useCallback
ensures thathandleClick
is only recreated whencount
changes, preventing unnecessary re-renders of theButton
component.- This is crucial for optimizing performance in components that rely on callbacks.
7. useRef Hook
The useRef
hook returns a mutable ref object that persists across renders. It’s typically used to reference DOM elements or store mutable values that don’t trigger re-renders when changed.
Syntax:
const refContainer = useRef(initialValue);
Example:
import React, { useRef } from 'react';
function TextInputWithFocus() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus the input</button>
</div>
);
}
How it Works:
useRef
allows you to access and manipulate DOM elements without causing re-renders.- In the example, the
inputRef
is used to focus the input element when the button is clicked.
Interview Questions Recap
Here are some commonly asked interview questions related to React Hooks:
- What is the difference between
useState
anduseReducer
, and when would you use one over the other? - How does
useEffect
differ from lifecycle methods likecomponentDidMount
andcomponentDidUpdate
? - What is the purpose of
useMemo
anduseCallback
, and how do they improve performance? - How do
useRef
anduseState
differ in terms of state persistence? - Explain how
useContext
simplifies the usage of context API compared to the traditional context methods.
Additional Essential JavaScript Interview Questions on Various Topics
- Web Workers: Empowering Frontend Development with This Ultimate Guide 2024
- Service Workers: Enhancing JavaScript Performance with This Definitive Guide 2024
- Arrow Functions vs. Normal Functions in JavaScript 2024
- Understanding call, bind, and apply in JavaScript 2024
- Web Security Essentials: Protecting Against CSRF, XSS, and Other Threats 2024
- Frontend Security: Best Practices for Authentication and Authorization 2024
- Web Storage Simplified: How to Use localStorage and sessionStorage in JavaScript 2024
- Javascript
Top Javascript Books to Read
Head First JavaScript Programming: A Brain-Friendly Guide [Paperback] Robson, Elisabeth and Freeman, Eric– by Elisabeth Robson and Eric Freeman | 1 January 2014
You Don`t Know JS: 6 Volume Set (Greyscale Indian Edition) Paperback – 1 January 2017– by Kyle Simpson (Author)
JavaScript: The Definitive Guide: Master the World’s Most-Used Programming Language, 7th Edition (Greyscale Indian Edition) [Paperback] David Flanagan – by David Flanagan | 11 July 2020
JavaScript and HTML5 Now Kindle Edition– by Kyle Simpson
Coding with Javascript for Dummies– by Chris Minnick and Eva Holland | 1 January 2015
JavaScript from Beginner to Professional: Learn JavaScript quickly by building fun, interactive, and dynamic web apps, games, and pages-by Laurence Lars Svekis, Maaike Van Putten, et al. | 15 December 2021