0% found this document useful (0 votes)
8 views39 pages

React JS Notes

React JS Notes

Uploaded by

ehaq14520
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views39 pages

React JS Notes

React JS Notes

Uploaded by

ehaq14520
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

1|Page

React JS Notes
What is State?
Definition:

State is a JavaScript object that holds information about the component’s current situation. When the state
changes, React re-renders the component to reflect the new data.

Example (Functional Component with useState):

import React, { useState } from 'react';

function Counter() {

const [count, setCount] = useState(0); // state variable 'count' with initial value 0

return (

<div>

<p>You clicked {count} times</p>

<button onClick={() => setCount(count + 1)}>

Click Me

</button>

</div>

);

useState(0):

• Initializes state variable count with value 0

• setCount is a function used to update the value of count

Key Points:

• State is local to the component (unless lifted or shared).

• Changing state causes re-rendering.

• Managed using useState in functional components.

• In class components, state is managed via this.state and this.setState().


2|Page

What is setCount in React?


In this line:

const [count, setCount] = useState(0);

• count → is the state variable

• setCount → is the function to update that variable

How does it work?

When you call:

setCount(count + 1);

1. It updates the state value (count)

2. React re-renders the component to reflect the new value

Why can't we do count++ directly?

You should never mutate state directly like this:

count++; Wrong

count = 10; Wrong

Because:

• React won’t know the state changed

• Component won’t re-render

Instead, always use setCount:

setCount(count + 1); Correct

setCount should be setDispaly, setShow etc anything it will be.

What are Hooks in React?


Hooks are functions that let you “hook into” React state and lifecycle features in functional components.

Before Hooks, these features were only available in class components

Why Hooks?

Hooks were introduced in React 16.8 to:

• Use state and lifecycle methods in functional components

• Make components cleaner, reusable, and easy to test

• Avoid complex patterns like HOCs and render props


3|Page

Commonly Used Hooks

Hook Purpose

useState Adds state to functional components

useEffect Handles side effects (API calls, etc.)

useContext Access context API (global data)

useRef Access or manipulate DOM directly

useMemo Memoize expensive calculations

Example: useEffect

import React, { useState, useEffect } from 'react';

function Timer() {

const [seconds, setSeconds] = useState(0);

useEffect(() => {

const timer = setInterval(() => setSeconds(s => s + 1), 1000);

return () => clearInterval(timer); // cleanup

}, []);

return <h2>Timer: {seconds}s</h2>;}

Rules of Hooks

1. Only call Hooks at the top level (not inside loops or conditions)

2. Only call Hooks from React functions (not normal JS functions)

How Add Multiple Condition?

1. Logical Operators (&&, ||)

Example with && (AND):

{isLoggedIn && hasPermission && <Dashboard />}

• If both isLoggedIn and hasPermission are true, then <Dashboard /> will render.

2. Ternary Operators (condition ? true : false)

Example:

{isAdmin? <AdminPanel /> : isUser ? <UserPanel /> : <GuestPanel />}

• Renders based on priority: Admin > User > Guest


4|Page

3. If-Else inside function body (JS block)

function MyComponent() {

if (!isLoggedIn) {

return <LoginPage />;

} else if (isAdmin) {

return <AdminPanel />;

} else {

return <UserPanel />; } }

4. Combining Conditions in JSX

{(user && user.isActive && user.role === "manager") && <ManagerDashboard />}

Example: Real Use Case

{isLoggedIn && (user.role === 'admin' || user.role === 'superuser') ? (<AdminPanel />) : ( <HomePage />)}

Where We Import Css File ?

1. Importing CSS in Component File

You can import a CSS file at the top of your component .js or .jsx file:

// MyComponent.jsx

import './MyComponent.css';

function MyComponent() {

return <div className="box">Hello!</div>;}

Make sure the CSS file is in the same folder or provide the correct relative path.

2. Import Global CSS in index.js or App.js

For global styles, import your main CSS (like index.css) at the top of your root files:

// index.js or App.js

import './index.css';

This style will apply globally across the entire app.

3. CSS in public Folder?

You can't directly import CSS from the public/ folder.


React doesn't process static files there.

If needed, add a <link> tag in public/index.html:

<link rel="stylesheet" href="%PUBLIC_URL%/styles.css" />

But it's not the React way — avoid this unless necessary.
5|Page

4. Importing External CSS (like Bootstrap)

Install Bootstrap:

npm install bootstrap

Then import it in index.js or App.js:

import 'bootstrap/dist/css/bootstrap.min.css';

5. CSS Modules (for scoped CSS)

If using CSS Modules, file name should be like MyComponent.module.css:

import styles from './MyComponent.module.css';

function MyComponent() {

return <div className={styles.box}>Box</div>;}

Summary Table

Type File Name Import in Usage

Component CSS MyComponent.css MyComponent.jsx .className

Global CSS index.css or app.css index.js Global across app

External CSS Bootstrap, etc. index.js Pre-built style frameworks

CSS Modules MyComponent.module.css MyComponent.jsx Scoped, modular styles

What are Props?


Props (short for properties) are read-only inputs that are passed from a parent component to a child
component.

Think of props as arguments passed to a function — they help you make components dynamic and reusable.

How do Props Work?

1. Passing Props

// ParentComponent.jsx

import Child from './Child';

function Parent() { return <Child name="Enamul" age={25} />;}

2. Receiving Props

// Child.jsx

function Child(props) { return (

<div>

<h2>Hello, {props.name}</h2>

<p>You are {props.age} years old</p>

</div> );}
6|Page

Example with Destructuring

Instead of props.name, you can do this:

function Child({ name, age }) {

return (

<div>

<h2>Hello, {name}</h2>

<p>You are {age} years old</p>

</div> );}

Key Points about Props

Feature Detail

Read-Only You cannot modify props inside child

Passed Downward From parent ➝ child, never upward

Dynamic You can pass data, functions, JSX, anything

Reusable Make components flexible and clean

Passing Functions as Props

function Parent() {

const greet = () => alert("Hello from Parent");

return <Child onClick={greet} />;}

function Child({ onClick }) {

return <button onClick={onClick}>Click Me</button>;}

Common Mistakes

• Trying to change props inside child:

props.name = "Hacked"; // Error

• Instead, use state in the parent to control and update the value, and pass it down.

What is a Controlled Component?


A controlled component is a form input element (like <input>, <textarea>, <select>) whose value is
controlled by React state.

It means React is the single source of truth for that input.


7|Page

Controlled vs Uncontrolled

Feature Controlled Component Uncontrolled Component

Value stored in React state DOM (via ref)

On change Uses onChange + setState Reads value using ref

Easy to validate Yes Hard

Recommended? Yes (for most cases) Only for simple quick tasks

Example of a Controlled Component

import React, { useState } from 'react';

function LoginForm() {

const [email, setEmail] = useState("");

const handleSubmit = (e) => {

e.preventDefault();

alert(`Submitted Email: ${email}`); };

return (

<form onSubmit={handleSubmit}>

<input type="email" value={email} onChange={(e) => setEmail(e.target.value)}

placeholder="Enter your email" />

<button type="submit">Submit</button>

</form> );}

Breakdown:

• value={email} → React controls the input value

• onChange updates the state using setEmail

• No data lives inside the input tag directly — React controls everything

Why Use Controlled Components?

For validation (e.g., required fields, regex)


To dynamically enable/disable buttons
To update multiple fields in sync
To save data to backend easily
8|Page

useEffect Hook
What is useEffect?

useEffect is a React Hook that allows you to perform side effects in functional components.

Side Effects = Things that happen outside the normal flow of returning JSX.
Examples:

• API calls / Fetching data

• Updating DOM manually

• Setting up timers (setTimeout, setInterval)

• Listening to events (like resize, scroll)

• Subscribing / unsubscribing

Why useEffect is needed?

Before hooks, if you wanted side effects, you used class lifecycle methods, like:

• componentDidMount

• componentDidUpdate

• componentWillUnmount

useEffect replaces all of those in functional components, making code simpler and reusable.

Basic Syntax

import { useEffect } from "react";

useEffect(() => { // code to run (side-effect) }, [dependencies]);

Understanding with Examples

Run on every render

useEffect(() => {

console.log("Component rendered or updated");});

No dependency array ⇒ this runs after every render (initial + every update)

Run only once – on Mount (componentDidMount)

useEffect(() => {

console.log("Component mounted");}, []);

Empty dependency array [] ⇒ Runs only one time (when component loads)

Run when specific value changes (componentDidUpdate)

useEffect(() => {

console.log("Count changed:", count);}, [count]);

Runs only when count value changes.


9|Page

Cleanup Function (componentWillUnmount)

Used for removing timers, unsubscribing, clearing intervals, etc.

useEffect(() => {

const timer = setInterval(() => {

console.log("Running timer"); }, 1000);

return () => {

clearInterval(timer);

console.log("Cleanup done"); };}, []);

The function inside return is the cleanup that runs when the component is unmounted.

Summary Table

Dependency Array When useEffect Runs

No array After every render

[] (empty) Only on first render (mount)

[var1, var2] When any dependency changes

Common Interview Points

• useEffect combines componentDidMount, componentDidUpdate, and componentWillUnmount in


one hook.

• The cleanup function runs before the component is removed OR before running the effect again (if
dependencies changed).

• Avoid infinite loops by setting correct dependencies.

Interview Questions (with brief answers)

Q1. What is useEffect used for?


A: To perform side effects in functional components like API calls, timers, subscriptions, etc.

Q2. What happens if you don’t give a dependency array?


A: The effect runs after every render.

Q3. How do you mimic componentDidMount?


A: By passing an empty array [] as dependencies.

Q4. What is the purpose of return inside useEffect?


A: It is the cleanup function, used for unmounting or clearing.

Q5. Can we have multiple useEffect in one component?


A: Yes, absolutely! React allows multiple useEffect hooks and each handles different logic.

Practical Use Cases

• Fetching data from API on component load

• Listening to window resize


10 | P a g e

• Form validation on input changes

• Animation triggers

• Auto-save draft data

Example: Fetch data with useEffect

import React, { useState, useEffect } from "react";

function Users() {

const [users, setUsers] = useState([]);

useEffect(() => {

fetch("https://jsonplaceholder.typicode.com/users")

.then(res => res.json())

.then(data => setUsers(data));

}, []);

return (

<div>

<h2>User List</h2>

{users.map(user => (

<p key={user.id}>{user.name}</p>

))}

</div> );}

Example: Updating Title on Count change

import React, { useState, useEffect } from "react";

function Counter() {

const [count, setCount] = useState(0);

useEffect(() => {

document.title = `Count = ${count}`;

}, [count]);

return (

<div>

<p>Count: {count}</p>

<button onClick={() => setCount(count + 1)}>Increment</button>

</div> );}
11 | P a g e

Loop in React (Rendering Lists with map())


In React, we do not use traditional for loops directly inside JSX.
Instead, we use the .map() method (a JavaScript array function) to loop and display elements.

Why use .map() in React?

• JSX wants to return something

• .map() returns a new array with transformed elements

• Perfect for rendering lists like menu items, cards, table rows, etc.

Basic Example

const numbers = [1, 2, 3, 4];

function NumbersList() {

return ( <div>

{numbers.map(num => (

<p key={num}>{num}</p>

))}

</div> );}

We looped through array and returned a <p> for each number.

Why key is important?

Whenever you loop in React, you MUST provide a unique key prop to each element.

✔ Helps React identify each item


✔ Avoids re-renders issues
✔ Key should be unique (id, index, etc.)

Looping array of objects

const users = [ { id: 1, name: "Enamul" }, { id: 2, name: "Nitesh" }, { id: 3, name: "Amit" }];

function UserList() {

return (

<ul>

{users.map(user => ( <li key={user.id}>{user.name}</li> ))}

</ul> );}

Rendering Components in a loop

function Card({ title }) {

return <div className="card">{title}</div>;}

function CardsScreen() {

const topics = ["HTML", "CSS", "React", "Node"];


12 | P a g e

return (

<div>

{topics.map((item, index) => (

<Card title={item} key={index} /> ))} </div> );}

Can we use for loop?

You can create an array manually using a for loop and then return it, but NOT inside return.

function Example() {

const items = [];

for (let i = 1; i <= 5; i++) { items.push(<p key={i}>Number: {i}</p>); }

return <div>{items}</div>;}

Bonus: Conditional Rendering + Loop

{items.map((item) => item.isActive ? <p key={item.id}>{item.name}</p> : null)}

Interview Tips on React Loops

• Use .map() for rendering multiple JSX elements.

• Always add key prop.

• Never write for loop directly inside JSX.

• Loop must return something.

Memory Table for Quick Revision

Concept Rule / Use

Main method array.map()

Inside return? Yes, with curly braces {}

Key prop Must be unique per item

for loop usage Outside return, store in array, then render

Mini Interview Questions

Q1. How do you render a list in React?


A: By using .map() function inside JSX and returning elements with a unique key.

Q2. Why is key prop important in loops?


A: Key helps React identify which elements changed, updated or removed for efficient rendering.

Q3. Can a simple for loop be used directly inside JSX?


A: No, JSX cannot have for blocks; instead, do it outside or use .map().
13 | P a g e

useRef Hook
What is useRef?

useRef is a React Hook that allows us to:

1. Access DOM elements directly

2. Store mutable values that can change without causing re-render

It returns a plain JavaScript object like this:

{ current: ... }

Syntax

import { useRef } from 'react';

const nameRef = useRef(initialValue);

Common Uses of useRef

1. Access / Focus DOM Elements

const inputRef = useRef(null);

function focusInput() {

inputRef.current.focus();}

return (

<div>

<input ref={inputRef} />

<button onClick={focusInput}>Focus</button>

</div>);

Here, inputRef.current gives direct DOM access to input element.

2. Store a Value without Re-render

const countRef = useRef(0);

function increase() {

countRef.current = countRef.current + 1;

console.log(countRef.current);}

Changing countRef.current does not re-render the component like useState does.

3. Store Previous Value

const [count, setCount] = useState(0);

const prevCountRef = useRef();

useEffect(() => { prevCountRef.current = count;});

return (
14 | P a g e

<div>

<p>Current: {count}</p>

<p>Previous: {prevCountRef.current}</p>

</div>);

Difference between useRef(), useState() and useEffect()

Hook Re-render on change? Use Case

useState Yes UI updates, reactivity

useRef No Reference elements, store values silently

useEffect -- run side effects after render

⚠ Important Notes

• useRef does not trigger re-render when its value changes.

• It returns the same object on every render (.current persists).

• Mainly used for imperative actions like focus, scrolling, etc.

Real Interview Points

• useRef is the functional component replacement for createRef.

• It combines both features: storing data & accessing DOM.

• It’s often used for:

o focusing input automatically

o storing interval IDs

o storing previous prop/state values

o skipping re-render

Simple Example: Auto focus input on page load

import { useRef, useEffect } from "react";

function AutoFocusInput() {

const inputElement = useRef(null);

useEffect(() => { inputElement.current.focus(); }, []);

return <input ref={inputElement} type="text" placeholder="Type here..." />;}

When to NOT use useRef?

• Don’t use it to manage UI state that should re-render (use useState for that).

• Don't mutate state variables directly via ref.


15 | P a g e

Interview QnA (Quick)

1. What is useRef hook?


It returns a mutable object used to access DOM elements directly or hold a value that persists without
causing re-render.

2. Difference between useState vs useRef?


useState causes re-render on change; useRef does not.

3. Can we store previous value of state?


Yes, with useRef in combination with useEffect.

4. Alternative to useRef in class components?


React.createRef()

Uncontrolled Component in React


What is an Uncontrolled Component?

An uncontrolled component is a form input element (like input, textarea) whose value is handled by the
DOM itself, not by React state.

That means:

• We don’t use useState to store each value.

• We access the value only when needed using useRef or direct DOM.

Think of uncontrolled components like normal HTML forms — browser manages the input value.

KEY POINT: useRef + defaultValue

<input type="text" ref={inputRef} defaultValue="Hello" />

Example of Uncontrolled Component

import React, { useRef } from "react";

function FormUncontrolled() {

const nameRef = useRef(null);

function handleSubmit(e) {

e.preventDefault();

alert("Name: " + nameRef.current.value); }

return ( <form onSubmit={handleSubmit}>

<input type="text" ref={nameRef} />

<button type="submit">Submit</button>

</form> );}

• Here we didn't use useState

• No binding with value={...}

• We accessed value using nameRef.current.value only on submit


16 | P a g e

Features of Uncontrolled Components

Feature Uncontrolled Component

Manages value DOM (Browser)

Controlled by React state? No

Use of useState? Not required

Use of useRef? Yes, mostly used to access value

Real-time validation? Harder or manual

When used? Simple forms, quick temp inputs, legacy code

Controlled vs Uncontrolled (Difference Table)

Aspect Controlled Component Uncontrolled Component

Form data stored in React state DOM (via ref)

Real-time control Easy (value changes re-render) Harder

Uses useState? Yes No

Uses useRef? Optional (rare) Yes (to access value)

Performance Slightly lower (more renders) Faster (less re-rendering)

Examples <input value={value} onChange={...} /> <input ref={inputRef}


defaultValue="" />

Why called “Uncontrolled”?

Because React is not controlling the input’s value –


It depends on the native DOM to control the input.

Benefits

• Simpler for small forms

• Less code if you don’t need validation

• Slightly better performance

Drawbacks

• Hard to validate or manipulate in real-time

• Hard to trigger UI updates on change

• Less common in modern React apps

Real Interview Questions

1. What is an uncontrolled component in React?


A component where form data is handled by the DOM itself, not by React state.
17 | P a g e

2. How do you access the value of an uncontrolled input?


Using useRef and reading current.value.

3. Difference between controlled and uncontrolled component?


Controlled uses React state, uncontrolled depends on DOM using ref.

React.forwardRef (Forward Ref)


What is Forward Ref?

Normally, refs cannot be passed through a component to reach a child DOM element directly.

Forward Ref is a technique that allows us to pass ref from parent down to a child component, so that parent
can get direct access to the DOM element created inside child.

React provides a built-in function:

const MyComponent = React.forwardRef((props, ref) => { // ...});

Why do we need forwardRef?

When you have a custom component (child) wrapping an input or button, the parent can’t directly access that
inner input using ref.

Example problem without forwardRef:

function InputChild() {

return <input type="text" />;}

function Parent() {

const inp = useRef();

return (

<div> <InputChild ref={inp} /> // This will NOT work. ref is undefined here </div> );}

Here, the ref does not reach the actual <input>.

Solution: React.forwardRef

const InputChild = React.forwardRef((props, ref) => { return <input type="text" ref={ref} />;});

function Parent() { const inputRef = useRef();

function focusInput() {

inputRef.current.focus();

} return ( <div>

<InputChild ref={inputRef} />

<button onClick={focusInput}>Focus</button>

</div> );}

Now the ref from Parent will point to the actual input element inside child.
18 | P a g e

Syntax Summary

const ComponentName = React.forwardRef((props, ref) => {

return <element ref={ref} />;

});

Uses / Real-life uses

• Custom Input Components (like for UI libraries)

• Reusable Input or Button components

• Passing focus or scroll control from parent

• For integrating with third-party libraries

⚠ Important Points (Asked in Interview)

• forwardRef only works with functional components.

• It takes a function with (props, ref) as parameters.

• The forwarded ref can be used in parent to access DOM.

• If you need both ref and props, you must wrap the component.

React 18 vs React 19?

There is no syntax change for forwardRef in React 19, same as React 18. Only difference is potential type
support with TypeScript. Core concept remains same.

Interview QnA Quick

Q1. Why can’t we normally use ref on child component?


Because refs only work directly on DOM elements, not on custom components.

Q2. How do we solve it?


By using React.forwardRef() so that ref passed from parent goes to the child DOM element.

Q3. What arguments does forwardRef take?


A function with (props, ref).

useTransition
What is useTransition?

useTransition is a React hook that helps you manage UI transitions without blocking the main UI.

It lets you mark certain updates as low priority (like filtering a big list) so that more important updates like
typing, clicking, UI response feel smooth.
19 | P a g e

Simple Meaning:

useTransition = “Make some state updates non-urgent, so UI doesn’t lag or freeze”

Syntax

import { useTransition } from 'react';

const [isPending, startTransition] = useTransition();

• startTransition(() => {...}) ⇒ wrap slow or heavy updates inside this

• isPending ⇒ boolean, true while the transition is running

Why useTransition?

Imagine you have a big list (10000 items).


When user types in a search box, filtering is slow and causes typing lag.

To fix it, wrap the heavy filtering inside startTransition.

Example Usage

Without useTransition (laggy UI):

const [input, setInput] = useState('');

const [list, setList] = useState(largeArray);

const handleChange = (e) => { setInput(e.target.value);

setList(largeArray.filter(item => item.includes(e.target.value)));};

With useTransition (smooth typing):

const [input, setInput] = useState('');

const [list, setList] = useState(largeArray);

const [isPending, startTransition] = useTransition();

function handleChange(e) {

const value = e.target.value;

setInput(value);

startTransition(() => {

const filtered = largeArray.filter(item => item.includes(value));

setList(filtered); });}

Summary Table

Property Description

startTransition Function to mark an update as low priority

isPending Boolean flag to check if transition is in progress

Typical Use-case Filtering, searching, expensive calculations


20 | P a g e

Benefits

• Keeps UI smooth

• Improves user experience

• Doesn’t block urgent updates (like typing)

⚠ Things to Remember

• Only works in React 18 or above

• Perfect for heavy updates, search filters, dynamic lists

• isPending can be used to show loading spinners or skeletons

🗣 Interview Questions

1. What problem does useTransition solve?

o It prevents UI from blocking when non-urgent updates happen.

2. Which React version introduced useTransition?

o React 18 (in concurrent features)

3. What does startTransition do?

o It wraps state updates to make them low-priority.

4. How can you show the user that transition is still running?

o Using isPending to conditionally show "Loading..." or skeleton.

useFormStatus() Hook
Note: useFormStatus is not a standard React hook available in plain React apps.
It is part of React DOM 18.2+ and especially used in Next.js App Router.

What is useFormStatus?

useFormStatus is a hook that allows you to check:

• whether a form is currently submitting

• if the submission succeeded or failed

• and to disable buttons, show loaders during form actions

Use Case

When you have a form that submits data (like login form, API action), you can use useFormStatus() in child
components (like a Submit button) to automatically know if the form is in "pending" / "submitting" state.

This way you can show Loading..., disable button, or show success message.
21 | P a g e

Syntax Basics

"use client";

import { useFormStatus } from 'react-dom';

function SubmitButton() {

const { pending } = useFormStatus();

return (

<button type="submit" disabled={pending}>

{pending ? "Submitting..." : "Submit"}

</button> );}

How does it work?

1. useFormStatus must be used inside a form component hierarchy.

2. Only works with server actions or form actions in Next.js.

3. It gives an object like:


{ pending, data, method, action }

Most important property:

Property Description

pending true when form is submitting

data FormData object (fields + values)

method HTTP method: 'POST', 'GET', etc.

action The form action URL or function

Simple Example (Next.js App Router)

// submit-form.js

"use client";

import { useFormStatus } from "react-dom";

function SubmitButton() {

const { pending } = useFormStatus();

return (

<button type="submit" disabled={pending}>

{pending ? "Sending..." : "Send"}

</button> );}

export default function ContactForm() {

async function sendData(formData) {


22 | P a g e

// server action

console.log(formData.get("name")); }

return (

<form action={sendData}>

<input type="text" name="name" />

<SubmitButton />

</form> );}

Observations

• When the form is submitting, pending = true

• We disabled button and show loader text

• It makes UI feel modern and user-friendly

Interview / Checklist

• useFormStatus is part of React DOM & mostly used in Next.js with app router & server actions

• It tells you whether a form is in pending state

• Very useful for UX

• You can only use it inside form components, not in random components

• It must be on client side component ("use client")

One Line Memory Tip

useFormStatus = "check if form is submitting"

Difference Between useTransition and useFormStatus

Feature / useTransition (React) useFormStatus (React DOM / Next.js)


Purpose

Main Goal Handle slow state updates without Track form submission state (pending or not)
blocking UI

Works in Any React app (React 18+) Primarily Next.js App Router with server actions

Usage For filtering, searching, heavy For disabling submit buttons, showing
computations “Submitting…” loaders

Returns [isPending, startTransition] array { pending, data, method, action } object

Triggers? Starts manually using startTransition() Automatically when form is submitted

Requires No No, but must be inside a <form> context


useRef?

Use-case Typing + filtering large lists Contact form submit button disabled while
example sending data
23 | P a g e

Conceptual Summary:

• useTransition
→ You decide which update is non-urgent.
→ You wrap heavy code inside startTransition(...).

• useFormStatus
→ You do not call it. It auto detects a <form> submission.
→ Just checks if form is "pending" (submitting) and updates UI (button disable, loader, etc).

Code Comparison

useTransition (manual)

const [isPending, startTransition] = useTransition();

function handleChange(value) {

startTransition(() => {

heavyFilter(value); });}

useFormStatus (form-based)

import { useFormStatus } from 'react-dom';

function SubmitBtn() {

const { pending } = useFormStatus();

return ( <button type="submit" disabled={pending}> {pending ? "Submitting…" : "Submit"} </button> );}

Easy One-Liner

✔ useTransition → manual slow updates


✔ useFormStatus → automatic form submission detection

Pure Component vs Impure (Normal) Component


React has two types of class components (in older/class-based React):

1. Regular/Impure Component (React.Component)

2. Pure Component (React.PureComponent)

Note: In functional components, this concept is similar to React.memo.

What is a Pure Component?

A Pure Component automatically prevents unnecessary re-rendering.


It does a shallow comparison of props and state.

• If props/state didn’t change → it skips re-render

• This improves performance

We use:

class Demo extends React.PureComponent {}


24 | P a g e

What is an Impure (Regular) Component?

A Regular Component (React.Component) re-renders every time its parent re-renders — even if props did not
change.
It doesn’t compare previous and new values.

class Demo extends React.Component {}.

Main Differences

Feature PureComponent Component (Impure)

Re-rendering Only if state/props changed (shallow) On every update (even unchanged)

ShouldComponentUpdate Already implemented internally We need to implement it manually

Used for Performance optimization Normal components

Functional Equivalent React.memo Normal functional component

Example:

class A extends React.PureComponent {

render() { console.log("Pure Component Rendered"); return <h1>{this.props.name}</h1>; }}

class B extends React.Component {

render() {

console.log("Regular Component Rendered");

return <h1>{this.props.name}</h1>;}}

// If parent re-renders with same props:

// A will NOT re-render

// B WILL re-render

⚠ Important Note

PureComponent only does shallow comparison. If props are objects/arrays and change by reference, it will re-
render.

For Functional Components

• PureComponent ≈ React.memo(MyComponent)

• Component ≈ normal function component

When to use PureComponent?

• When your component gets the same props often

• To improve performance by avoiding useless renders

• But it should not use complex nested objects as props


25 | P a g e

Interview Questions Summary

• Q. What is PureComponent?
→ A class component that does shallow comparison of props/state and avoids unnecessary renders.

• Q. Difference with normal Component?


→ Regular component does not compare props, so it always re-renders.

• Q. Functional Alternative of PureComponent?


→ React.memo()

One-liner Memory:

PureComponent = Smart component that skips re-renders unless data changes.

What is Derived State in React?


Derived state is state that is calculated from props or other state, not stored directly.

Instead of keeping a duplicate value in state, we derive that value using logic.

Why avoid derived state when possible?

Because keeping multiple sources of truth leads to bugs!

• If you store the same info twice (state + props), they can get out of sync

• React docs recommend calculating when needed instead of storing

Example of BAD Derived State

function Example({ price }) {

const [taxedPrice, setTaxedPrice] = useState(price * 1.18);

// What if price prop changes? Our taxedPrice might become wrong unless we sync again.}

➡ This is bad because taxedPrice is derived from price, so better derive directly.

Good way (No derived state)

function Example({ price }) {

const taxedPrice = price * 1.18; // derived on the fly

return <p>Price with Tax: {taxedPrice}</p>;}

When you MUST use derived state?

In some cases, yes, derived state is necessary:

• When you need to do expensive calculation only once (avoid recalculation)

• When you need a copy that user can modify separately

• Or use derived state and sync with useEffect:

function Example({ price }) {

const [taxedPrice, setTaxedPrice] = useState(0);


26 | P a g e

useEffect(() => { setTaxedPrice(price * 1.18); }, [price]); // keep syncing when price changes

return <p>Taxed Price: {taxedPrice}</p>}

Warning:

If you use derived state incorrectly, you'll face:

• Infinite loops

• Stale values

• Unexpected UI bugs

Key Points for Interviews:

• Derived state means storing values that are calculated from other state/props

• Prefer computing them during render instead of storing

• Use useEffect to sync derived state only if necessary

• Avoid duplication of logic or two sources of truth

Real Interview Question:

Why is derived state considered an anti-pattern sometimes?

Answer:
Because it risks making state out-of-sync with props, breaking React's single source of truth principle. Use
memoization (useMemo) or compute values directly while rendering.

One-Line Summary

Derived State = duplicate or computed state based on props/state — avoid storing it unless really needed.

What does "Lifting State Up" mean?

When two or more child components need to share or sync the same data/state, we move that state up to their
common parent component.The parent becomes the single source of truth, and passes data + functions down
via props.

Why do we lift state?

• To avoid mismatched data between siblings

• To keep data centralized

• So that children can communicate through the parent

Example Scenario

You have two components:

• Component A: an input field

• Component B: displays what user typed

Normally, both components don't know each other's state. So we lift the state up into their parent.
27 | P a g e

Code Example of Lifting State Up

import React, { useState } from "react";

// Child A

function InputChild({ handleChange }) {

return (

<input type="text" onChange={(e) => handleChange(e.target.value)} />

);}

// Child B

function DisplayChild({ text }) {

return <h3>User typed: {text}</h3>;}

// Parent

function ParentComponent() {

const [data, setData] = useState("");

function updateValue(val) {

setData(val); } return (

<div>

<InputChild handleChange={updateValue} />

<DisplayChild text={data} />

</div> );}

export default ParentComponent;

Summary in Plain Words

• State lives in Parent

• Child A updates Parent via function

• Parent passes updated data to Child B

• Both children are synced via Parent's state

Advantages of Lifting State Up

Benefit Description

Single source of truth Only one state, less bugs

Sibling communication One child sends data to another via parent

React recommended pattern Promotes unidirectional data flow


28 | P a g e

⚠ When NOT to lift state?

• If only one component uses that data

• If siblings don't need to share data

• Too much lifting makes parent very large (called Prop Drilling issue). In that case use Context API.

Interview Questions

Q1. What is lifting state up?


Answer: Moving shared state from child component(s) into their common parent so they can share data.

Q2. Why is it useful?


Answer: It prevents duplication of state and keeps the data consistent between child components.

Q3. What problem can occur if you lift too much state?
Answer: It leads to "prop drilling" and tightly coupled parent which becomes hard to maintain.

One-Line Memory

Lifting state up = Put data in parent so siblings can communicate & stay in sync.

Updating Object in React State


In React, you should never mutate state directly.
That means: don't do state.myObj.key = value;

Instead, you need to create a new copy of that object, update the copy, and then set the new object using
setState or setX.

Functional Component Example

Assume state is an object:

const [user, setUser] = useState({

name: "Enamul",

age: 25,

city: "Lucknow"

});

Correct way to update one property:

setUser((prevUser) => ({

...prevUser,

age: 26

}));

We use the spread operator (...) to copy previous object, then update the specific key.
29 | P a g e

Add new property to object:

setUser((prevUser) => ({

...prevUser,

profession: "Developer"}));

Wrong Way (mutation):

user.age = 26; // Wrong

setUser(user); // Still wrong because you mutated original

Example in Class Component

this.state = {

user: { name: "Amit", age: 22, city: "Delhi" }

};

// Later:

this.setState((prev) => ({

user: {

...prev.user,

city: "Mumbai"

}));

Updating Nested Object or Array inside State

If you have nested objects:

const [state, setState] = useState({

user: { name: "John", address: { city: "NY", pin: 123 } }

});

setState((prev) => ({

...prev,

user: {

...prev.user,

address: {

...prev.user.address,

city: "LA"

}}));
30 | P a g e

Key Interview Points

• Always treat state as immutable

• Use spread operator or Object.assign()

• Use callback version of setState or setX if updating based on previous value

• For arrays: use .map() or .filter() + spread

One line summary:

Updating object state in React = copy old object → change → set new object (never mutate directly)

✍ Quick MCQ

Q: Which one correctly updates object state?

a) user.age = 25; setUser(user);


b) setUser({ ...user, age: 25 })

Updating Arrays in React State


Just like objects, arrays in React state must not be mutated directly.
We should always create a new array and then call setState or setX.

Functional Component Example

const [items, setItems] = useState([1, 2, 3]);

Add / Push new value

Wrong (mutate):

items.push(4); //

setItems(items);

Correct:

setItems([...items, 4]);

Remove item

Remove by index or value using filter()

setItems(items.filter((item) => item !== 2));

Update item in array

Example: update an object in array or update value at index

setItems(items.map((item) => item === 2 ? 20 : item ));


31 | P a g e

Example with Array of Objects

const [users, setUsers] = useState([

{ id: 1, name: "Enamul" },

{ id: 2, name: "Nitesh" }

]);

// Update user name

setUsers(users.map(user =>

user.id === 2 ? { ...user, name: "Raghunath" } : user));

Full Add/Edit/Delete Example

// Add new object

setUsers([...users, { id: 3, name: "Amit" }]);

// Delete by id

setUsers(users.filter(u => u.id !== 1));

Key Rules (Important)

Goal Correct Method

Add [...oldItems, newItem]

Remove .filter()

Update/Replace .map()

Do NOT mutate original push, splice, sort

Why no direct mutation?

• It won't trigger React re-render

• React compares state by reference

• Mutation breaks immutability and can cause bugs

Bonus: Updating nested arrays

const [data, setData] = useState({

numbers: [1,2,3]

});

// add to inner array

setData(prev => ({

...prev,

numbers: [...prev.numbers, 4]}));


32 | P a g e

✍ Interview QnA

Q: How do you update an array in state?


→ By creating a new copy of array using spread, filter, or map, then updating with setState.

Q: Why can't we use push()?


→ Because push() mutates original array which React won't detect as a new state.

One-line Summary:

Always create a new array (spread/map/filter) instead of mutating while updating array in React state.

What is useActionState?
useActionState is a hook used to handle form submissions + server actions + state update in one step.

It simplifies:

• Form state handling

• Submitting data to a server function

• Updating UI with the result

This is typically used with server actions (like export async function action(formData) in Next.js 13/14 App
Router).

Syntax

const [state, action, isPending] = useActionState(asyncAction, initialState);

What each part means?

Part Meaning

initialState default value of state

asyncAction(formData, prevState) function that runs with form submit

state current state / result

action function used as form action

isPending boolean: true while form is submitting

When to use it?

• When submitting forms in Next.js App Router with server actions

• When you want to update state based on result of server action

• Simplify form + state logic without using useState + useFormStatus separately

Key Features

• You no longer need separate useState to store the result

• No need to manually manage loading state — isPending gives it

• Combines server action + client state nicely


33 | P a g e

Important Notes

• Only works in React DOM with server actions (Next.js App Router)

• Used in client component, but wraps a server function

• Not available in simple CRA or Vite React apps

Interview Style Points

• useActionState helps manage form state that depends on the result of an async server action.

• It returns an array: [state, actionFunction, isPending]

• Encourages progressive enhancement and simplicity in Next.js forms

One-line Memory

useActionState = useState + formAction + loader all in one hook (for server form submissions)

Quick Comparison

Hook Use Case

useState General local state in client app

useTransition For async UI transitions (no server connection)

useFormStatus Check if form submission is pending

useActionState Submit form + get result + auto state update

Custom Hooks in React


What is a Custom Hook?

A Custom Hook is basically a reusable function that uses other React hooks inside it (like useState, useEffect,
etc.) and follows the rules of hooks.

It helps you extract and reuse common logic between components.

It starts with the word use


It is NOT a component
It is just a function that may return data, functions or JSX

Why do we use Custom Hooks?

• To avoid code duplication

• To keep components clean

• To separate logic from UI

• To share features (like fetching logic, form logic, animation behavior) across multiple components
34 | P a g e

Example: Create a custom hook called useCounter

import { useState } from "react";

function useCounter(initialValue = 0) {

const [count, setCount] = useState(initialValue);

function increment() { setCount(prev => prev + 1); }

function decrement() {

setCount(prev => prev - 1); }

return { count, increment, decrement };}

export default useCounter;

Using the custom hook in any component

import useCounter from "./useCounter";

function CounterComponent() {

const { count, increment, decrement } = useCounter(5);

return ( <div>

<h2>Count: {count}</h2>

<button onClick={increment}>+</button>

<button onClick={decrement}>-</button>

</div> );}

Common Types of Custom Hooks

Use-case Example Hook Name

Fetch data from API useFetch, useFetchData

Form Input handling useInput, useForm

Window width tracking useWindowSize

Debounce search values useDebounce

Local Storage sync useLocalStorage

Another example: useFetch

import { useState, useEffect } from "react";

function useFetch(url) {

const [data, setData] = useState(null);

const [loading, setLoading] = useState(true);

useEffect(() => {

fetch(url)

.then(res => res.json()) .then(data => {


35 | P a g e

setData(data);

setLoading(false); });

}, [url]);

return { data, loading };}

export default useFetch;

Rules for Custom Hooks

• Must start with use

• Can call other hooks inside it

• Must follow Rules of hooks (only call at top-level, not inside loops or conditions)

Interview Q&A

Q1. What is a custom hook?


→ A reusable function that uses React hooks to share logic between components.

Q2. Why would you use a custom hook?


→ To remove duplicate logic and keep components simple.

Q3. Does a custom hook return JSX?


→ Usually No, it returns values or functions — but you can return JSX if needed (rare).

Q4. Can a custom hook call another custom hook?


→ Yes, they are just functions.

One line memory

Custom Hooks = Your own reusable React logic, wrapped in a function that starts with use.

React Context API


What is Context API?

React Context API is a built-in feature that allows you to share data globally across components without
passing props manually at every level.

It helps when multiple components need access to the same data (like user info, theme, language, authentication,
etc.)

Problem: Prop Drilling

Prop drilling = passing data from parent → child → grandchild → great-grandchild just to reach the last
component. This becomes messy in large apps.

Solution = Create a Context and provide data at top-level, then consume it anywhere.
36 | P a g e

Main Steps of Using Context

Step Description

1. Create context using createContext()

2. Wrap components inside a Context Provider

3. Consume it using useContext() or Context.Consumer

Code Example

Step 1: Create Context File

import { createContext } from "react";

const UserContext = createContext();

export default UserContext;

Step 2: Create Provider component

import React, { useState } from "react";

import UserContext from "./UserContext";

export default function UserProvider({ children }) {

const [user, setUser] = useState("Enamul");

return (

<UserContext.Provider value={{ user, setUser }}>

{children}

</UserContext.Provider> );}

Step 3: Wrap in App.js

import UserProvider from "./UserProvider";

import Dashboard from "./Dashboard";

function App() {

return (

<UserProvider>

<Dashboard />

</UserProvider> );}

Step 4: Consume Anywhere

import { useContext } from "react";

import UserContext from "./UserContext";

function Dashboard() {

const { user } = useContext(UserContext);


37 | P a g e

return <h1>Welcome, {user}!</h1>;}

Benefits of Context API

• Avoids prop drilling

• Central and clean state sharing

• Great for theme, auth, language, settings

⚠ When NOT to use it?

• Not a replacement for global state libraries (Redux, Zustand)

• Not good for very frequent updates (like big forms)

• Too many contexts can cause re-renders

React Interview Questions on Context API

Q1. What problem does Context API solve?


→ Avoids prop drilling — allows passing data to deeply nested components.

Q2. How do you consume context in a functional component?


→ Using useContext(MyContext).

Q3. What alternative to Context for global state?


→ Redux, Zustand, Recoil, MobX, etc.

Summary Table

Concept Meaning

createContext() Create context object

Provider Supplies the data to children

useContext hook Access context value easily in functional components

Prop Drilling Passing props layer-by-layer unnecessarily

One-Line Memory Hack:

Context = "Global data provider" inside React, to avoid passing props manually.
38 | P a g e

React Router — Router vs Routes vs Route


React Router is a library used for navigation between pages or components in a React app.

In React Router v6 (latest), we mainly use:

• <BrowserRouter>

• <Routes>

• <Route>

Let’s break each one:

<BrowserRouter> (also called Router)

• The main parent component that wraps the whole app

• It enables routing functionality in your app

• It listens to URL changes

import { BrowserRouter } from 'react-router-dom';

<BrowserRouter>

<App />

</BrowserRouter>

<Routes>

• It acts like a container for all individual routes

• It replaces old <Switch> in v6

• It allows only the first matching <Route> to render

<BrowserRouter>

<Routes>

// all <Route> goes here

</Routes>

</BrowserRouter>

<Route>

• It defines the actual path and the component to show

• Syntax: <Route path="/somepath" element={<ComponentName />} />

Example:

<Route path="/" element={<Home />} />

<Route path="/about" element={<About />} />

Simple Full Example


39 | P a g e

import { BrowserRouter, Routes, Route } from "react-router-dom";

import Home from "./Home";

import About from "./About";

function App() {

return (

<BrowserRouter>

<Routes>

<Route path="/" element={<Home />} />

<Route path="/about" element={<About />} />

</Routes>

</BrowserRouter> );}

Summary Table

Concept Use / Role

BrowserRouter Wraps whole app; enables routing

Routes Wrapper for all Route definitions

Route Associates a URL path to a component

BONUS: Link Component

To navigate without reloading page, we use:

import { Link } from 'react-router-dom';

<Link to="/about">About</Link>

⚠ Common Beginner Confusion

Old React Router v5 New v6 (latest)

<BrowserRouter> Same

<Switch> replaced by <Routes>

<Route component={Home} /> now <Route element={<Home />} />

Interview style memory hack:

BrowserRouter gives routing power,


Routes groups the paths,
Route defines each path with a component

You might also like