2. Hooks in React.js

useState()
The
useState
hook is used to manage state inside a functional component. It returns an array with two valuesThe current state.
A function to update the state.
import React, { useState } from "react"; function Counter() { const [count, setCount] = useState(0); // on every state change our component is re-render(reload) return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } export default Counter;
useState(0)
initializes the state with0
.setCount(count + 1)
updates the state.React re-renders the component when state changes.
useEffect()
The
useEffect
hook is used for side effects in React components, such as:Fetching data from an API
Updating the DOM
Subscribing to events
import React, { useState, useEffect } from "react";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
alert("Component updated! Count:", count); // on chnage state -> our component re-render so alert message will shown
});
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Timer;
useEffect() dependencies
useEffect(callback) | Runs after every render. |
useEffect(callback, []) | Runs only after component is mount (on first render) |
useEffect(callback, [dependency]) | Runs when the dependency changes |
useContext()
The
useContext
hook allows us to use React’s Context API, which provides a way to pass data down the component tree without using props.After creating context API that contain state and functions , we directally access these varibales and functionsin any component from contxt API
How to create context API -: create context folder in src and AppContext.js(any name) file in it.
//inside AppContext.js file
export const AppContext = createContext(null) // create context
export function AppContextProvider ({children}){ // here children is our </App> that bound in index.js
const [cartItems, setCartItems]= useState({}); // 1.write all reusable states here
const [token , setToken] = useState("");
//2.write reusable functions
//3. Also manage authentication by getting and setting token from local storage
//4.
const value = {
cartItems ,
setToken
}
//5.
return (
<AppContext.Provider value={value}>
{children}
</AppContext.Provider>
)
}
Next step is to bound our </App> inside<AppContextProvider> in index.js
// How to use above state in out react component
//Blog.jsx
import { AppContext } from '../../context/AppContext';
import React, { useContext } from 'react'
const Cart = () => {
const{cartItems, token}= useContext(AppContext); // here we use useCOntext() to use react context API
return (
)
}
Key Points:
createContext()
creates a global state.useContext(ThemeContext)
allows access to context values.
useMemo()
useMemo
hook optimizes the performance by memorizing or caching the values and preventing unneccsary recalculations.import React, { useState, useMemo } from "react"; function ExpensiveComponent() { const [count, setCount] = useState(0); const [number, setNumber] = useState(5); const factorial = useMemo(() => { // it contain one callback function and dependecies console.log("Calculating Factorial..."); return number <= 0 ? 1 : number * factorial(number - 1); }, [number]); return ( <div> <p>Factorial: {factorial}</p> <button onClick={() => setNumber(number + 1)}>Increase</button> <button onClick={() => setCount(count + 1)}>Re-render ({count})</button> </div> ); } export default ExpensiveComponent;
Key Points:
useMemo(() => compute(), [dependencies])
caches values. (compute function will only run when our dependency changes otherwise it will return prevoius result that is memorized previously)Improves performance by avoiding unnecessary recalculations.
useCallback()
useCallback()
hook memorizes(freeze) functions to prevent unncessary re-renders.import React, { useState, useCallback } from "react"; function Button({ handleClick }) { return <button onClick={handleClick}>Click Me</button>; } function Parent() { const [count, setCount] = useState(0); const memoizedFunction = useCallback(() => { console.log("Button clicked!"); }, []); return ( <div> <p>Count: {count}</p> <Button handleClick={memoizedFunction} /> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } export default Parent;
Key Points:
Prevents child components from re-rendering unnecessarily.
useMemo() → memorizes values that is returned by the value
useCallback() → memorizes reference of function to recreate .(freeze the function to re-create on each render)
useReducer()
The
useReducer
hook is used as an alternative touseState
when managing complex state logic.It is used in large-scale applications.
import React, { useReducer } from "react"; const initialState = 0; function reducer(state, action) { // state is count and action is object comes from dispatch if(action.type === "increment"){ return state +1; } else{ return state -1; } } } function Counter() { const [count, dispatch] = useReducer(reducer, initialState); return ( <div> <p>Count: {count}</p> <button onClick={() => dispatch({ type: "increment" })}>+</button> // onClick + button dispatch function it trigger reducer function that take {type:"increment} as a object <button onClick={() => dispatch({ type: "decrement" })}>-</button> </div> ); } export default Counter;
Key Points:
useReducer(reducer, initialState)
returns[state, dispatch]
.dispatch({ type: "increment" })
triggers state updates.
useRef()
The
useRef
hook provides a way to reference DOM elements or persist values across renders without triggering re-renders.It return an object that is access by using .current
useState()→ make UI re-redner
useRef ()→ UI not render
Ex:1
const c = useRef(0) // we access 0 using .current c.current = c.current+1; // UI not render
Ex:2- Primary use → DOM me se kisi bhi element to directaly access ya change kar paay.
// Let click on first button it may change the color of another button so we need to store res of // fisrt button const btn1Ref = useRef() //Now link that button with this <button ref={btn1Ref}> Button 1 </button> //Now on click button 2 button one color chnge <button onClick= {()=>btn1Ref.current.style.backgroundcolor="red"}> Button 2 </button>
Ex:3 - Onclick button our input select file from device
import React, { useRef } from "react"; function InputFocus() { const input1Ref = useRef(null); const input2Ref = useRef(null); return ( <div> <input ref={input1Ref} type="text" /> <input ref={input2Ref} type="file" className="hidden" /> <button onClick={() => input1Ref.current.focus()}>Focus Input</button> // it focussed input <button onClick={() => input2Ref.current.click()}>Select</button> // onclick this button it choose file from device </div> ); } export default InputFocus;
Key Points:
useRef(initialValue)
creates a mutable object.ref.current
allows direct manipulation.
Custom Hooks(
useSomething()
)A Custom Hook in React is a JavaScript function that reuses logic across multiple components.
and use built-in hooks like
useState
,useEffect
,useRef
, etc.import { useState, useEffect } from "react"; function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const fetchData = async () => { try { const response = await fetch(url); if (!response.ok) throw new Error("Failed to fetch data"); const result = await response.json(); setData(result); } catch (err) { setError(err.message); } }; fetchData(); }, [url]); return { data, loading}; } export default useFetch;
How to use this :
import React from "react"; import useFetch from "./useFetch"; function Users() { const { data, loading, error } = useFetch("https://jsonplaceholder.typicode.com/users"); if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error}</p>; return ( <ul> {data.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> ); } export default Users;
Interview Questions
What is the difference between useState and useReducer?
useState
is best for simple state management.useReducer
is used for complex state logic with multiple actions.
What does useEffect with an empty dependency array do?
It runs only once when the component mounts.
When should you use useMemo?
When you need to cache expensive computations to improve performance.
What is the difference between useMemo and useCallback?
useMemo
returns a memoized value.useCallback
returns a memoized function.
Why is useRef useful?
It allows accessing DOM elements and persisting values without causing re-renders.
Why do we use custom hooks?
Reduces code duplication
Improves maintainability
Makes components cleaner and easier to understand
Encourages reusability of stateful logic
Subscribe to my newsletter
Read articles from Ayush Rajput directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
