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
- Master JavaScript Modules vs. CommonJS: The Ultimate 2024 Guide
- Ultimate Guide to Mastering JavaScript Symbols, Scope, and Immutability in 2024
- Mastering SOLID Principles in JavaScript: A Guide with Code Examples 2024
- Mastering Design Patterns for Frontend Developers: A Comprehensive Guide
- Understanding JavaScript Closures: A Comprehensive Guide
- JavaScript Event Loop: A Deep Dive with Examples 2024
- 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
- localStorage vs sessionStorage: The Ultimate Guide to Mastering Web Storage in JavaScript for 2024
- Variable Scopes Demystified: The Ultimate Beginner’s Guide to JavaScript 2024
- Javascript
React Js Interview questions:
- Mastering React Server-Side Rendering (SSR): A Deep Dive into SSR, CSR, and SSG
- Code Splitting and Lazy Loading in React: Boost Performance in Large Applications
- Higher-Order Components (HOC): Are They Still Relevant in 2024?
Mastering the useReducer Hook in React 2024: The Ultimate Guide for Advanced State Management - How Does React’s Context API Work? When Would You Use It Instead of a State Management Library Like Redux?
- Mastering React Hooks: The Ultimate 2024 Guide with Detailed Examples
- Virtual DOM: How Does React’s Reconciliation Algorithm Work?
- useEffect Hook in React: In-Depth Explanation and Performance Optimization
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