0% found this document useful (0 votes)
11 views48 pages

ReactJs (Basic. Intermediate, Advanced)

The document provides a comprehensive overview of ReactJS, covering essential concepts such as JSX, components (functional vs class), props, state management with useState, lifecycle methods, event handling, conditional rendering, and lists with keys. It includes code examples to illustrate each concept, emphasizing best practices and performance considerations. Additionally, it delves into intermediate topics like the useEffect hook for managing side effects and optimizing component behavior.

Uploaded by

AryanKukreti
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)
11 views48 pages

ReactJs (Basic. Intermediate, Advanced)

The document provides a comprehensive overview of ReactJS, covering essential concepts such as JSX, components (functional vs class), props, state management with useState, lifecycle methods, event handling, conditional rendering, and lists with keys. It includes code examples to illustrate each concept, emphasizing best practices and performance considerations. Additionally, it delves into intermediate topics like the useEffect hook for managing side effects and optimizing component behavior.

Uploaded by

AryanKukreti
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

# **ReactJs_Basic.

md**

## 1. What is JSX in React?


**Answer:** JSX (JavaScript XML) is a syntax extension that allows writing HTML-like code
within JavaScript. It gets transpiled to `[Link]()` calls by Babel. JSX makes React
components more readable and intuitive. It supports embedding JavaScript expressions within
curly braces `{}`, HTML attributes use camelCase (`className`, `onClick`), and must return a
single parent element (Fragment `<>` for multiple).

**Code Example:**
```jsx
// JSX example
const element = (
<div className="container">
<h1>Hello, {userName}!</h1>
<p>Current count: {count}</p>
<button onClick={handleClick}>Click me</button>
</div>
);

// Gets transpiled to:


[Link](
'div',
{ className: 'container' },
[Link]('h1', null, 'Hello, ', userName, '!'),
[Link]('p', null, 'Current count: ', count),
[Link]('button', { onClick: handleClick }, 'Click me')
);
```

---

## 2. React Components: Functional vs Class


**Answer:** React components are reusable UI pieces. Functional components are JavaScript
functions returning JSX, simpler with hooks. Class components are ES6 classes extending
`[Link]`, using `render()` method and lifecycle methods. Since React 16.8, functional
components with hooks are preferred for new code. Both accept props and can maintain state
(functional via `useState`, class via `[Link]`).

**Code Example:**
```jsx
// Functional Component
function Greeting(props) {
return <h1>Hello, {[Link]}!</h1>;
}

// With arrow function


const Greeting = ({ name }) => <h1>Hello, {name}!</h1>;

// Class Component
class Greeting extends [Link] {
render() {
return <h1>Hello, {[Link]}!</h1>;
}
}

// Usage
<Greeting name="John" />
```

---

## 3. Props in React Components


**Answer:** Props (properties) are read-only data passed from parent to child components. They
enable component reusability and customization. Props are immutable within child components.
Use destructuring for cleaner access. Can pass functions as props for child-to-parent
communication. Default props and prop types (with TypeScript or PropTypes) ensure data
integrity.

**Code Example:**
```jsx
// Parent component passing props
function App() {
const user = { name: 'John', age: 30 };

return (
<div>
<UserCard
name={[Link]}
age={[Link]}
onUpdate={handleUpdate}
/>
<ProductCard title="Laptop" price={999} />
</div>
);
}

// Child component receiving props


function UserCard(props) {
return (
<div className="card">
<h2>{[Link]}</h2>
<p>Age: {[Link]}</p>
<button onClick={() => [Link]([Link] + 1)}>
Increment Age
</button>
</div>
);
}

// With destructuring
function ProductCard({ title, price, discount = 0 }) {
return (
<div>
<h3>{title}</h3>
<p>Price: ${price - discount}</p>
</div>
);
}
```

---

## 4. State Management with useState


**Answer:** State represents component's internal data that can change over time, triggering re-
renders. `useState` hook returns current state value and setter function. State updates are
asynchronous and batched. Use functional updates when new state depends on previous state.
Multiple state variables can be used for independent data.

**Code Example:**
```jsx
import { useState } from 'react';

function Counter() {
// Basic state
const [count, setCount] = useState(0);

// Object state
const [user, setUser] = useState({
name: 'John',
age: 30,
email: 'john@[Link]'
});

// Array state
const [items, setItems] = useState(['Apple', 'Banana', 'Orange']);

const increment = () => {


// Functional update for dependent state
setCount(prevCount => prevCount + 1);
};

const updateName = () => {


// Update object state correctly
setUser(prevUser => ({
...prevUser,
name: 'Jane'
}));
};

const addItem = () => {


setItems(prevItems => [...prevItems, 'Mango']);
};

return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>

<p>User: {[Link]}, Age: {[Link]}</p>


<button onClick={updateName}>Update Name</button>
<ul>
{[Link]((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
<button onClick={addItem}>Add Item</button>
</div>
);
}
```

---

## 5. Component Lifecycle Methods (Class Components)


**Answer:** Lifecycle methods are specific to class components, called at different phases:
Mounting (`constructor`, `render`, `componentDidMount`), Updating (`shouldComponentUpdate`,
`render`, `componentDidUpdate`), Unmounting (`componentWillUnmount`).
`componentDidMount` for side effects like API calls. `shouldComponentUpdate` for performance
optimization. `componentWillUnmount` for cleanup.

**Code Example:**
```jsx
class UserProfile extends [Link] {
constructor(props) {
super(props);
[Link] = { user: null, loading: true };
[Link]('Constructor called');
}

componentDidMount() {
[Link]('Component mounted');
// API call
fetchUser([Link])
.then(user => [Link]({ user, loading: false }));

// Event listener
[Link]('resize', [Link]);
}

componentDidUpdate(prevProps, prevState) {
[Link]('Component updated');
// Fetch new user if userId changed
if ([Link] !== [Link]) {
[Link]({ loading: true });
fetchUser([Link])
.then(user => [Link]({ user, loading: false }));
}
}

shouldComponentUpdate(nextProps, nextState) {
// Only update if userId changed or loading state changed
return [Link] !== [Link] ||
[Link] !== [Link];
}
componentWillUnmount() {
[Link]('Component will unmount');
// Cleanup
[Link]('resize', [Link]);
}

handleResize = () => {
[Link]('Window resized');
};

render() {
[Link]('Render called');
const { user, loading } = [Link];

if (loading) return <div>Loading...</div>;

return (
<div>
<h1>{[Link]}</h1>
<p>Email: {[Link]}</p>
</div>
);
}
}
```

---

## 6. Event Handling in React


**Answer:** React events are synthetic wrappers around native DOM events for cross-browser
consistency. Use camelCase naming (`onClick`, `onChange`). Pass function references, not calls
(`onClick={handleClick}` not `onClick={handleClick()}`). Use arrow functions or bind in
constructor for class methods. Event pooling improves performance but requires
`[Link]()` for async access.

**Code Example:**
```jsx
function EventHandlers() {
const [text, setText] = useState('');
const [count, setCount] = useState(0);

// Simple click handler


const handleClick = () => {
setCount(count + 1);
};

// Input change handler


const handleChange = (event) => {
setText([Link]);
};

// Form submit handler


const handleSubmit = (event) => {
[Link](); // Prevent page reload
[Link]('Submitted:', text);
};

// Mouse events
const handleMouseEnter = () => {
[Link]('Mouse entered');
};

// Inline event handler with parameters


const handleItemClick = (itemId) => {
[Link]('Item clicked:', itemId);
};

return (
<div>
{/* Click event */}
<button onClick={handleClick}>Click me: {count}</button>

{/* Input event */}


<input
type="text"
value={text}
onChange={handleChange}
placeholder="Type something..."
/>

{/* Form event */}


<form onSubmit={handleSubmit}>
<input type="text" value={text} onChange={handleChange} />
<button type="submit">Submit</button>
</form>

{/* Mouse events */}


<div
onMouseEnter={handleMouseEnter}
onMouseLeave={() => [Link]('Mouse left')}
style={{ padding: '20px', background: '#f0f0f0' }}
>
Hover over me
</div>

{/* Event with parameter */}


<ul>
{['Item 1', 'Item 2', 'Item 3'].map((item, index) => (
<li
key={index}
onClick={() => handleItemClick(index)}
style={{ cursor: 'pointer' }}
>
{item}
</li>
))}
</ul>
</div>
);
}
```

---

## 7. Conditional Rendering in React


**Answer:** Conditional rendering displays different UI based on conditions. Methods include: if/
else statements, ternary operator `? :`, logical `&&` operator, switch statements, and early returns.
For complex conditions, extract logic to separate functions or components. Conditional
rendering optimizes performance by avoiding unnecessary DOM nodes.

**Code Example:**
```jsx
function UserGreeting({ isLoggedIn, userRole }) {
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);

// Early return for loading/error states


if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;

return (
<div>
{/* if/else with ternary */}
<h1>
{isLoggedIn ? 'Welcome back!' : 'Please sign in'}
</h1>

{/* Logical && operator */}


{isLoggedIn && (
<div>
<p>You have 3 new messages</p>
<button>View Messages</button>
</div>
)}

{/* Multiple conditions */}


<div>
{userRole === 'admin' && <AdminPanel />}
{userRole === 'user' && <UserDashboard />}
{userRole === 'guest' && <GuestView />}
{!['admin', 'user', 'guest'].includes(userRole) && <DefaultView />}
</div>

{/* Inline conditional rendering */}


<div>
{isLoggedIn ? (
<Profile user={user} />
):(
<LoginForm />
)}
</div>
{/* Using variables */}
let content;
if (userRole === 'admin') {
content = <AdminTools />;
} else if (userRole === 'moderator') {
content = <ModeratorTools />;
} else {
content = <BasicTools />;
}

return <div>{content}</div>;
</div>
);
}

// Helper component for complex conditions


function RoleBasedContent({ role }) {
switch(role) {
case 'admin':
return <AdminContent />;
case 'editor':
return <EditorContent />;
case 'viewer':
return <ViewerContent />;
default:
return <GuestContent />;
}
}
```

---

## 8. Lists and Keys in React


**Answer:** Rendering lists uses `map()` to transform arrays into React elements. Keys help
React identify which items changed/added/removed. Use stable, unique IDs from data when
possible. Index as key is acceptable only if list is static (no reordering/filtering). Keys should be
unique among siblings but not globally. Incorrect keys cause performance issues and state bugs.

**Code Example:**
```jsx
function ProductList({ products, onRemove }) {
// Good: Using unique ID from data
return (
<ul>
{[Link](product => (
<li key={[Link]}>
<ProductItem product={product} />
<button onClick={() => onRemove([Link])}>Remove</button>
</li>
))}
</ul>
);
}
function TodoList({ todos }) {
// Acceptable: Index as key for static list
return (
<ul>
{[Link]((todo, index) => (
<li key={index}>{[Link]}</li>
))}
</ul>
);
}

function UserTable({ users }) {


// Complex list with nested components
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{[Link](user => (
<UserRow
key={[Link]}
user={user}
/>
))}
</tbody>
</table>
);
}

// Separate component for list items


function UserRow({ user }) {
return (
<tr>
<td>{[Link]}</td>
<td>{[Link]}</td>
<td>{[Link]}</td>
<td>
<button>Edit</button>
<button>Delete</button>
</td>
</tr>
);
}

// Filtered list
function ActiveUsers({ users }) {
const activeUsers = [Link](user => [Link]);
return (
<div>
<h3>Active Users ({[Link]})</h3>
<ul>
{[Link](user => (
<li key={[Link]}>{[Link]}</li>
))}
</ul>
</div>
);
}

// List with conditional rendering inside


function TaskList({ tasks }) {
return (
<div>
{[Link] === 0 ? (
<p>No tasks found</p>
):(
<ul>
{[Link](task => (
<li key={[Link]}>
<span style={{
textDecoration: [Link] ? 'line-through' : 'none'
}}>
{[Link]}
</span>
{[Link] === 'high' && <span> </span>}
</li>
))}
</ul>
)}
</div>
);
}
```

# **ReactJs_Intermediate.md**

## 1. useState Hook Deep Dive


**Answer:** `useState` manages component state in functional components. Returns array with
current state and setter function. State updates are asynchronous and batched. Use functional
updates when new state depends on previous state (`setCount(prev => prev + 1)`). Initial state
can be function for expensive computations. Multiple independent state variables recommended
over single object.

**Code Example:**
```jsx
import { useState } from 'react';

function UserProfile() {
// Multiple state variables
const [name, setName] = useState('');
const [age, setAge] = useState(0);
const [isAdmin, setIsAdmin] = useState(false);

// Lazy initial state


const [preferences, setPreferences] = useState(() => {
// Expensive computation
const saved = [Link]('prefs');
return saved ? [Link](saved) : getDefaultPrefs();
});

// Functional updates
const incrementAge = () => {
setAge(prevAge => prevAge + 1);
};

// Batched updates
const resetUser = () => {
setName('');
setAge(0);
setIsAdmin(false);
// All updates batched together
};

// Object state (update correctly)


const [user, setUser] = useState({ name: '', age: 0 });

const updateUserName = (newName) => {


setUser(prev => ({ ...prev, name: newName }));
};

// State with complex logic


const [items, setItems] = useState([]);

const addItem = (item) => {


setItems(prev => {
if ([Link](item)) return prev;
return [...prev, item];
});
};

return (
<div>
<input value={name} onChange={e => setName([Link])} />
<button onClick={incrementAge}>Age: {age}</button>
<input
type="checkbox"
checked={isAdmin}
onChange={e => setIsAdmin([Link])}
/>
</div>
);
}
```
---

## 2. useEffect Hook for Side Effects


**Answer:** `useEffect` handles side effects in functional components: data fetching,
subscriptions, manual DOM manipulation. Runs after render. Cleanup function prevents memory
leaks. Dependency array controls execution: empty `[]` runs once (mount), with dependencies
runs when they change, no array runs after every render. Use multiple effects for separation of
concerns.

**Code Example:**
```jsx
import { useState, useEffect } from 'react';

function DataFetcher({ userId }) {


const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

// Fetch data on mount and when userId changes


useEffect(() => {
let isMounted = true;

const fetchData = async () => {


try {
setLoading(true);
const response = await fetch(`/api/users/${userId}`);
const result = await [Link]();

if (isMounted) {
setData(result);
setError(null);
}
} catch (err) {
if (isMounted) {
setError([Link]);
}
} finally {
if (isMounted) {
setLoading(false);
}
}
};

fetchData();

// Cleanup function
return () => {
isMounted = false;
// Cancel any pending requests
};
}, [userId]); // Dependency array

// Event listener effect (cleanup important)


useEffect(() => {
const handleResize = () => {
[Link]('Window resized');
};

[Link]('resize', handleResize);

return () => {
[Link]('resize', handleResize);
};
}, []); // Empty array = run once on mount

// Document title effect


useEffect(() => {
[Link] = data ? `User: ${[Link]}` : 'Loading...';
}, [data]); // Update when data changes

// Timer effect with cleanup


useEffect(() => {
const intervalId = setInterval(() => {
[Link]('Timer tick');
}, 1000);

return () => clearInterval(intervalId);


}, []);

if (loading) return <div>Loading...</div>;


if (error) return <div>Error: {error}</div>;

return (
<div>
<h1>{[Link]}</h1>
<p>Email: {[Link]}</p>
</div>
);
}
```

---

## 3. useContext for Global State Management


**Answer:** `useContext` provides way to pass data through component tree without prop
drilling. Create context with `[Link]()`, provide value with `[Link]`,
consume with `useContext(Context)`. Ideal for theme, authentication, language preferences.
Combine with `useReducer` for complex state logic. Not replacement for state management
libraries in large apps.

**Code Example:**
```jsx
import { createContext, useContext, useState } from 'react';

// Create context
const ThemeContext = createContext();
const UserContext = createContext();
// Provider component
function AppProvider({ children }) {
const [theme, setTheme] = useState('light');
const [user, setUser] = useState(null);

const toggleTheme = () => {


setTheme(prev => prev === 'light' ? 'dark' : 'light');
};

const login = (userData) => {


setUser(userData);
};

const logout = () => {


setUser(null);
};

return (
<[Link] value={{ theme, toggleTheme }}>
<[Link] value={{ user, login, logout }}>
{children}
</[Link]>
</[Link]>
);
}

// Custom hook for context


function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within ThemeProvider');
}
return context;
}

function useUser() {
return useContext(UserContext);
}

// Component using context


function Navbar() {
const { theme, toggleTheme } = useTheme();
const { user, logout } = useUser();

return (
<nav className={`navbar ${theme}`}>
<div>My App</div>
<div>
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'Dark' : 'Light'} Mode
</button>
{user ? (
<>
<span>Welcome, {[Link]}</span>
<button onClick={logout}>Logout</button>
</>
):(
<span>Please login</span>
)}
</div>
</nav>
);
}

function ThemedButton() {
const { theme } = useTheme();

return (
<button className={`btn btn-${theme}`}>
Themed Button
</button>
);
}

// App structure
function App() {
return (
<AppProvider>
<Navbar />
<ThemedButton />
<UserProfile />
</AppProvider>
);
}

function UserProfile() {
const { user } = useUser();

if (!user) return <div>Please login to view profile</div>;

return (
<div>
<h2>Profile</h2>
<p>Name: {[Link]}</p>
<p>Email: {[Link]}</p>
</div>
);
}
```

---

## 4. Custom Hooks for Logic Reuse


**Answer:** Custom hooks extract component logic into reusable functions. Must start with
`use` prefix. Can call other hooks. Enable sharing stateful logic without changing component
hierarchy. Common patterns: `useFetch`, `useLocalStorage`, `useForm`, `useDebounce`. Keep
hooks focused on single responsibility. Test hooks with React Testing Library.
**Code Example:**
```jsx
import { useState, useEffect, useCallback } from 'react';

// Custom hook for localStorage


function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = [Link](key);
return item ? [Link](item) : initialValue;
} catch (error) {
[Link](error);
return initialValue;
}
});

const setValue = useCallback((value) => {


try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
[Link](key, [Link](valueToStore));
} catch (error) {
[Link](error);
}
}, [key, storedValue]);

return [storedValue, setValue];


}

// Custom hook for API fetching


function useFetch(url, options = {}) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const abortController = new AbortController();

const fetchData = async () => {


setLoading(true);
setError(null);

try {
const response = await fetch(url, {
...options,
signal: [Link]
});

if (![Link]) {
throw new Error(`HTTP ${[Link]}`);
}

const result = await [Link]();


setData(result);
} catch (err) {
if ([Link] !== 'AbortError') {
setError([Link]);
}
} finally {
setLoading(false);
}
};

fetchData();

return () => [Link]();


}, [url, options]);

return { data, loading, error, refetch: () => {} };


}

// Custom hook for debounced value


function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);

useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);

return () => clearTimeout(timer);


}, [value, delay]);

return debouncedValue;
}

// Custom hook for form handling


function useForm(initialValues = {}, validate) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const [touched, setTouched] = useState({});

const handleChange = useCallback((e) => {


const { name, value, type, checked } = [Link];
setValues(prev => ({
...prev,
[name]: type === 'checkbox' ? checked : value
}));

if (validate) {
setErrors(prev => ({
...prev,
[name]: validate(name, value)
}));
}
}, [validate]);

const handleBlur = useCallback((e) => {


const { name } = [Link];
setTouched(prev => ({ ...prev, [name]: true }));
}, []);

const resetForm = useCallback(() => {


setValues(initialValues);
setErrors({});
setTouched({});
}, [initialValues]);

return {
values,
errors,
touched,
handleChange,
handleBlur,
resetForm,
setValues
};
}

// Usage example
function UserForm() {
const { values, errors, handleChange, handleBlur } = useForm(
{ name: '', email: '' },
(name, value) => {
if (name === 'email' && ![Link]('@')) {
return 'Invalid email';
}
return '';
}
);

const [theme, setTheme] = useLocalStorage('theme', 'light');


const debouncedSearch = useDebounce([Link], 500);
const { data: users, loading } = useFetch('/api/users');

return (
<div className={`app ${theme}`}>
<input
name="name"
value={[Link]}
onChange={handleChange}
onBlur={handleBlur}
/>
{[Link] && <span>{[Link]}</span>}

<button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>


Toggle Theme
</button>
</div>
);
}
```
---

## 5. Performance Optimization Techniques


**Answer:** React performance optimization includes: `[Link]` for component
memoization, `useMemo` for expensive computations, `useCallback` for function references,
code splitting with `[Link]`, virtualization for long lists, avoiding unnecessary re-renders, and
proper key usage. Profile with React DevTools to identify bottlenecks. Optimize only when
needed (premature optimization).

**Code Example:**
```jsx
import { useState, useMemo, useCallback, memo } from 'react';

// Memoized component (shallow comparison)


const ExpensiveComponent = memo(function ExpensiveComponent({ items, onSelect }) {
[Link]('ExpensiveComponent rendered');

// Expensive computation memoized


const processedItems = useMemo(() => {
[Link]('Processing items...');
return [Link](item => ({
...item,
processed: [Link] * 2
}));
}, [items]);

return (
<ul>
{[Link](item => (
<li key={[Link]} onClick={() => onSelect([Link])}>
{[Link]} - {[Link]}
</li>
))}
</ul>
);
});

// Parent component
function OptimizedParent() {
const [count, setCount] = useState(0);
const [items, setItems] = useState([
{ id: 1, name: 'Item 1', value: 10 },
{ id: 2, name: 'Item 2', value: 20 }
]);

// Memoized callback (prevents unnecessary re-renders)


const handleSelect = useCallback((itemId) => {
[Link]('Selected:', itemId);
}, []); // Empty dependency = stable reference

// Memoized derived value


const totalValue = useMemo(() => {
return [Link]((sum, item) => sum + [Link], 0);
}, [items]);

return (
<div>
<button onClick={() => setCount(c => c + 1)}>
Re-render parent: {count}
</button>

<button onClick={() => setItems([...items, { id: [Link](), name: 'New', value: 30 }])}>
Add Item
</button>

<p>Total Value: {totalValue}</p>

{/* This component only re-renders when items change */}


<ExpensiveComponent
items={items}
onSelect={handleSelect}
/>

{/* Virtualized list for large datasets */}


<VirtualizedList data={largeDataSet} />
</div>
);
}

// Virtualized list example (conceptual)


function VirtualizedList({ data, itemHeight = 50, visibleCount = 10 }) {
const [scrollTop, setScrollTop] = useState(0);
const containerRef = useRef();

const startIndex = [Link](scrollTop / itemHeight);


const endIndex = [Link](startIndex + visibleCount, [Link]);

const visibleItems = useMemo(() => {


return [Link](startIndex, endIndex);
}, [data, startIndex, endIndex]);

return (
<div
ref={containerRef}
style={{ height: visibleCount * itemHeight, overflow: 'auto' }}
onScroll={() => setScrollTop([Link])}
>
<div style={{ height: [Link] * itemHeight }}>
{[Link]((item, index) => (
<div
key={[Link]}
style={{
position: 'absolute',
top: (startIndex + index) * itemHeight,
height: itemHeight
}}
>
{[Link]}
</div>
))}
</div>
</div>
);
}
```

---

## 6. Error Boundaries for Graceful Error Handling


**Answer:** Error boundaries catch JavaScript errors in child component tree, display fallback UI
instead of crashing. Class component with `static getDerivedStateFromError()` and
`componentDidCatch()`. Only catches errors in render/lifecycle methods, not event handlers/
async code. Wrap parts of app for granular error recovery. Use `ErrorBoundary` component from
libraries or custom implementation.

**Code Example:**
```jsx
import { Component } from 'react';

class ErrorBoundary extends Component {


constructor(props) {
super(props);
[Link] = {
hasError: false,
error: null,
errorInfo: null
};
}

static getDerivedStateFromError(error) {
return { hasError: true, error };
}

componentDidCatch(error, errorInfo) {
// Log error to service
[Link]('Error caught by boundary:', error, errorInfo);
[Link]({ errorInfo });

// Send to error tracking service


if ([Link]) {
[Link](error, errorInfo);
}
}

resetError = () => {
[Link]({
hasError: false,
error: null,
errorInfo: null
});
if ([Link]) {
[Link]();
}
};

render() {
if ([Link]) {
if ([Link]) {
return [Link]({
error: [Link],
errorInfo: [Link],
resetError: [Link]
});
}

return (
<div className="error-boundary">
<h2>Something went wrong</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
<summary>Error Details</summary>
{[Link] && [Link]()}
<br />
{[Link]?.componentStack}
</details>
<button onClick={[Link]}>Try again</button>
</div>
);
}

return [Link];
}
}

// Usage examples
function App() {
return (
<div>
{/* Global error boundary */}
<ErrorBoundary
onError={(error) => sendToAnalytics(error)}
fallback={({ resetError }) => (
<div>
<h1>App Crashed</h1>
<button onClick={resetError}>Restart App</button>
</div>
)}
>
<Header />

{/* Granular error boundaries */}


<ErrorBoundary>
<MainContent />
</ErrorBoundary>
<ErrorBoundary>
<Sidebar />
</ErrorBoundary>

<ErrorBoundary>
<UserDashboard />
</ErrorBoundary>
</ErrorBoundary>
</div>
);
}

// Component that might throw


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

useEffect(() => {
fetchData().then(setData);
}, []);

// Simulate error
if (!data) {
throw new Error('Data failed to load');
}

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

// Safe component wrapper


function SafeComponent({ children, fallback = null }) {
try {
return children();
} catch (error) {
[Link]('Component error:', error);
return fallback || <div>Component failed</div>;
}
}
```

---

## 7. Higher-Order Components (HOCs)


**Answer:** HOCs are functions that take a component and return enhanced component. Enable
cross-cutting concerns: authentication, logging, data fetching. Use composition over inheritance.
Pass through props with spread operator. Avoid mutating original component. Name with `with`
prefix. Modern alternative: custom hooks for logic reuse, render props for dynamic composition.

**Code Example:**
```jsx
import { Component } from 'react';

// HOC for authentication


function withAuth(WrappedComponent) {
return class extends Component {
constructor(props) {
super(props);
[Link] = {
isAuthenticated: false,
user: null,
loading: true
};
}

componentDidMount() {
[Link]();
}

checkAuth = async () => {


try {
const token = [Link]('token');
if (token) {
const user = await verifyToken(token);
[Link]({ isAuthenticated: true, user, loading: false });
} else {
[Link]({ isAuthenticated: false, loading: false });
}
} catch (error) {
[Link]({ isAuthenticated: false, loading: false });
}
};

login = (credentials) => {


// Login logic
[Link]({ isAuthenticated: true });
};

logout = () => {
[Link]('token');
[Link]({ isAuthenticated: false, user: null });
};

render() {
const { isAuthenticated, user, loading } = [Link];

if (loading) {
return <div>Loading authentication...</div>;
}

return (
<WrappedComponent
{...[Link]}
isAuthenticated={isAuthenticated}
user={user}
login={[Link]}
logout={[Link]}
checkAuth={[Link]}
/>
);
}
};
}

// HOC for loading state


function withLoading(WrappedComponent) {
return function({ isLoading, ...props }) {
if (isLoading) {
return <div className="loading-spinner">Loading...</div>;
}

return <WrappedComponent {...props} />;


};
}

// HOC for error handling


function withErrorBoundary(WrappedComponent) {
return class extends Component {
state = { hasError: false, error: null };

static getDerivedStateFromError(error) {
return { hasError: true, error };
}

componentDidCatch(error, errorInfo) {
[Link]('Error:', error, errorInfo);
}

render() {
if ([Link]) {
return (
<div className="error-container">
<h3>Something went wrong</h3>
<p>{[Link]?.message}</p>
</div>
);
}

return <WrappedComponent {...[Link]} />;


}
};
}

// HOC for data fetching


function withDataFetching(url) {
return function(WrappedComponent) {
return class extends Component {
state = { data: null, loading: true, error: null };

async componentDidMount() {
try {
const response = await fetch(url);
const data = await [Link]();
[Link]({ data, loading: false });
} catch (error) {
[Link]({ error: [Link], loading: false });
}
}

render() {
const { data, loading, error } = [Link];

return (
<WrappedComponent
{...[Link]}
data={data}
loading={loading}
error={error}
/>
);
}
};
};
}

// Usage examples
const UserProfileWithAuth = withAuth(UserProfile);
const UserProfileWithAuthAndLoading = withLoading(withAuth(UserProfile));

// Component using multiple HOCs


function EnhancedDashboard() {
return (
<div>
<UserProfileWithAuth />
<DataTableWithFetching />
</div>
);
}

// Modern alternative with custom hooks


function useAuth() {
const [user, setUser] = useState(null);
// ... auth logic
return { user, login, logout };
}

function UserProfile() {
const { user, login, logout } = useAuth();
// Component logic
}
```

# **ReactJs_Advanced.md**

## 1. useMemo for Expensive Computations


**Answer:** `useMemo` memoizes expensive calculations, returning cached value until
dependencies change. Prevents unnecessary recalculations on re-renders. Use for derived state,
complex transformations, or component props that don't change often. Not needed for primitive
operations. Compare with `useCallback` for functions. Profile performance before adding
optimization.

**Code Example:**
```jsx
import { useMemo, useState } from 'react';

function ProductList({ products, filter, sortBy }) {


// Memoized filtered and sorted products
const processedProducts = useMemo(() => {
[Link]('Processing products...');

let result = products;

// Apply filter
if (filter) {
result = [Link](product =>
[Link]().includes([Link]()) ||
[Link]().includes([Link]())
);
}

// Apply sorting
if (sortBy) {
result = [...result].sort((a, b) => {
if (sortBy === 'price') return [Link] - [Link];
if (sortBy === 'name') return [Link]([Link]);
return 0;
});
}

return result;
}, [products, filter, sortBy]); // Recompute only when these change

// Memoized statistics
const stats = useMemo(() => {
const total = [Link]((sum, p) => sum + [Link], 0);
const average = [Link] > 0 ? total / [Link] : 0;
const categories = [...new Set([Link](p => [Link]))];

return { total, average, categoryCount: [Link] };


}, [processedProducts]);

// Memoized component for expensive rendering


const ProductTable = useMemo(() => {
return function({ products }) {
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Category</th>
</tr>
</thead>
<tbody>
{[Link](product => (
<ProductRow key={[Link]} product={product} />
))}
</tbody>
</table>
);
};
}, []); // Empty deps - created once

return (
<div>
<p>Showing {[Link]} products</p>
<p>Total value: ${[Link](2)}</p>
<p>Average price: ${[Link](2)}</p>

<ProductTable products={processedProducts} />


</div>
);
}

function ProductRow({ product }) {


// Memoized expensive formatting
const formattedPrice = useMemo(() => {
return new [Link]('en-US', {
style: 'currency',
currency: 'USD'
}).format([Link]);
}, [[Link]]);

// Memoized complex styling


const rowStyle = useMemo(() => ({
backgroundColor: [Link] === 0 ? '#ffcccc' : 'white',
fontWeight: [Link] ? 'bold' : 'normal'
}), [[Link], [Link]]);

return (
<tr style={rowStyle}>
<td>{[Link]}</td>
<td>{formattedPrice}</td>
<td>{[Link]}</td>
</tr>
);
}
```

---

## 2. useCallback for Stable Function References


**Answer:** `useCallback` returns memoized callback function that only changes when
dependencies change. Prevents unnecessary re-renders of child components receiving callback
as prop. Essential when passing callbacks to optimized child components (`[Link]`). Use
with `[Link]` for complete optimization. Empty dependency array creates stable function.
**Code Example:**
```jsx
import { useState, useCallback, memo } from 'react';

// Memoized child component


const ExpensiveChild = memo(function ExpensiveChild({ onClick, data }) {
[Link]('Child rendered');
return (
<div>
<button onClick={() => onClick([Link])}>Click me</button>
<p>Data: {[Link]}</p>
</div>
);
});

function ParentComponent() {
const [count, setCount] = useState(0);
const [items, setItems] = useState([
{ id: 1, value: 'Item 1' },
{ id: 2, value: 'Item 2' }
]);

// BAD: New function on every render


// const handleClick = (id) => {
// [Link]('Clicked:', id);
// };

// GOOD: Stable function reference


const handleClick = useCallback((id) => {
[Link]('Clicked:', id);
// Can use state/props if in dependencies
}, []); // Empty array = never changes

// Callback with dependencies


const handleItemUpdate = useCallback((id, newValue) => {
setItems(prev => [Link](item =>
[Link] === id ? { ...item, value: newValue } : item
));
}, []); // setItems is stable, no deps needed

// Callback using current state


const handleComplexAction = useCallback(() => {
// Using count from closure
[Link]('Current count:', count);
// For callbacks that need latest state, use functional update
setCount(c => c + 1);
}, []); // No count dependency needed with functional update

// Event handler factory pattern


const createItemHandler = useCallback((itemId) => {
return () => {
[Link]('Item clicked:', itemId);
};
}, []);

return (
<div>
<button onClick={() => setCount(c => c + 1)}>
Re-render Parent: {count}
</button>

{/* Child won't re-render unnecessarily */}


{[Link](item => (
<ExpensiveChild
key={[Link]}
onClick={handleClick}
data={item}
/>
))}

{/* Multiple callbacks */}


<ButtonGroup
onAdd={useCallback(() => setItems(prev => [...prev, {
id: [Link](),
value: 'New Item'
}]), [])}
onClear={useCallback(() => setItems([]), [])}
onSort={useCallback(() => {
setItems(prev => [...prev].sort((a, b) =>
[Link]([Link])
));
}, [])}
/>
</div>
);
}

// Component receiving multiple callbacks


const ButtonGroup = memo(function ButtonGroup({ onAdd, onClear, onSort }) {
[Link]('ButtonGroup rendered');

return (
<div>
<button onClick={onAdd}>Add Item</button>
<button onClick={onClear}>Clear All</button>
<button onClick={onSort}>Sort</button>
</div>
);
});

// Custom hook returning callbacks


function useArrayOperations(initialArray) {
const [array, setArray] = useState(initialArray);

const add = useCallback((item) => {


setArray(prev => [...prev, item]);
}, []);
const remove = useCallback((id) => {
setArray(prev => [Link](item => [Link] !== id));
}, []);

const update = useCallback((id, updates) => {


setArray(prev => [Link](item =>
[Link] === id ? { ...item, ...updates } : item
));
}, []);

return { array, add, remove, update };


}
```

---

## 3. [Link] for Component Memoization


**Answer:** `[Link]` is a higher-order component that memoizes functional components,
preventing re-renders if props haven't changed. Performs shallow comparison by default.
Accepts custom comparison function as second argument. Use for expensive-to-render
components with stable props. Combine with `useCallback` for callback props. Not needed for
simple components.

**Code Example:**
```jsx
import { memo, useState } from 'react';

// Simple memoized component


const UserCard = memo(function UserCard({ user, onSelect }) {
[Link]('UserCard rendered:', [Link]);

return (
<div className="user-card" onClick={() => onSelect([Link])}>
<h3>{[Link]}</h3>
<p>{[Link]}</p>
<p>Role: {[Link]}</p>
</div>
);
});

// With custom comparison function


const UserCardWithCustomCompare = memo(
function UserCard({ user, onSelect }) {
return (
<div className="user-card" onClick={() => onSelect([Link])}>
<h3>{[Link]}</h3>
<p>Role: {[Link]}</p>
</div>
);
},
// Custom comparison: only re-render if name or role changed
(prevProps, nextProps) => {
return (
[Link] === [Link] &&
[Link] === [Link]
);
}
);

// Complex memoized component


const DataTable = memo(function DataTable({
data,
columns,
sortBy,
onSort,
rowRenderer
}) {
[Link]('DataTable rendered');

const sortedData = [...data].sort((a, b) => {


if (!sortBy) return 0;
return a[sortBy] > b[sortBy] ? 1 : -1;
});

return (
<table>
<thead>
<tr>
{[Link](col => (
<th
key={[Link]}
onClick={() => onSort([Link])}
>
{[Link]}
</th>
))}
</tr>
</thead>
<tbody>
{[Link](item => (
<tr key={[Link]}>
{[Link](col => (
<td key={[Link]}>
{rowRenderer ? rowRenderer(item, col) : item[[Link]]}
</td>
))}
</tr>
))}
</tbody>
</table>
);
});

// Parent component
function UserDashboard() {
const [users, setUsers] = useState([
{ id: 1, name: 'John Doe', email: 'john@[Link]', role: 'admin' },
{ id: 2, name: 'Jane Smith', email: 'jane@[Link]', role: 'user' },
// ... more users
]);

const [selectedUserId, setSelectedUserId] = useState(null);


const [searchTerm, setSearchTerm] = useState('');

// Memoized filtered users


const filteredUsers = [Link](user =>
[Link]().includes([Link]()) ||
[Link]().includes([Link]())
);

// Stable callback
const handleSelectUser = (userId) => {
setSelectedUserId(userId);
};

return (
<div>
<input
type="text"
placeholder="Search users..."
value={searchTerm}
onChange={(e) => setSearchTerm([Link])}
/>

<div className="user-list">
{[Link](user => (
<UserCard
key={[Link]}
user={user}
onSelect={handleSelectUser}
/>
))}
</div>

{/* Table with memoized row renderer */}


<DataTable
data={users}
columns={[
{ key: 'name', title: 'Name' },
{ key: 'email', title: 'Email' },
{ key: 'role', title: 'Role' }
]}
rowRenderer={memo(function RowRenderer(item, column) {
// Custom rendering logic
if ([Link] === 'role') {
return (
<span className={`role-badge role-${[Link]}`}>
{[Link]}
</span>
);
}
return item[[Link]];
})}
/>
</div>
);
}

// When NOT to use [Link]


const SimpleButton = ({ onClick, children }) => (
<button onClick={onClick}>{children}</button>
);
// Usually not worth memoizing - simple component
```

---

## 4. Code Splitting with [Link] and Suspense


**Answer:** Code splitting divides bundle into smaller chunks loaded on demand. `[Link]()`
enables component-level splitting. `Suspense` displays fallback while loading. Use with `import()`
dynamic imports. Route-based splitting common with React Router. Prefetching improves
perceived performance. Error boundaries catch loading failures. SSR requires different approach.

**Code Example:**
```jsx
import { lazy, Suspense, useState } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';

// Lazy load components


const HomePage = lazy(() => import('./pages/HomePage'));
const AboutPage = lazy(() => import('./pages/AboutPage'));
const ContactPage = lazy(() => import('./pages/ContactPage'));
const UserProfile = lazy(() => import('./components/UserProfile'));
const ProductDetails = lazy(() => import('./components/ProductDetails'));

// Lazy load with prefetching


const Dashboard = lazy(() =>
import(/* webpackPrefetch: true */ './pages/Dashboard')
);

// Lazy load with named exports


const AdminPanel = lazy(() =>
import('./components/AdminPanel').then(module => ({
default: [Link]
}))
);

// Custom loading component


function LoadingSpinner() {
return (
<div className="loading-container">
<div className="spinner"></div>
<p>Loading...</p>
</div>
);
}

// Error boundary for lazy loading failures


class LazyLoadErrorBoundary extends [Link] {
state = { hasError: false };

static getDerivedStateFromError(error) {
return { hasError: true };
}

render() {
if ([Link]) {
return (
<div className="error-container">
<h3>Failed to load component</h3>
<button onClick={() => [Link]()}>
Retry
</button>
</div>
);
}

return [Link];
}
}

function App() {
const [showChart, setShowChart] = useState(false);

// Conditional lazy loading


const ChartComponent = lazy(() => import('./components/Chart'));

return (
<Router>
<LazyLoadErrorBoundary>
<div className="app">
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
<Link to="/dashboard">Dashboard</Link>
</nav>

<Suspense fallback={<LoadingSpinner />}>


<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
<Route path="/contact" element={<ContactPage />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route
path="/users/:id"
element={
<Suspense fallback={<div>Loading user...</div>}>
<UserProfile />
</Suspense>
}
/>
<Route
path="/products/:id"
element={
<Suspense fallback={<div>Loading product...</div>}>
<ProductDetails />
</Suspense>
}
/>
</Routes>
</Suspense>

{/* Conditional lazy loading */}


<button onClick={() => setShowChart(true)}>
Show Chart
</button>

{showChart && (
<Suspense fallback={<div>Loading chart...</div>}>
<ChartComponent />
</Suspense>
)}

{/* Nested Suspense for granular control */}


<Suspense fallback={<LoadingSpinner />}>
<MainContent>
<Suspense fallback={<div>Loading sidebar...</div>}>
<Sidebar />
</Suspense>
<Suspense fallback={<div>Loading feed...</div>}>
<NewsFeed />
</Suspense>
</MainContent>
</Suspense>
</div>
</LazyLoadErrorBoundary>
</Router>
);
}

// Preloading components on interaction


function PreloadExample() {
const [preloaded, setPreloaded] = useState(false);

// Preload component on hover


const handleMouseEnter = () => {
import('./components/HeavyComponent').then(module => {
// Component is now in cache
setPreloaded(true);
});
};
return (
<div>
<button
onMouseEnter={handleMouseEnter}
onClick={() => {
// Will load instantly if preloaded
const HeavyComponent = lazy(() =>
import('./components/HeavyComponent')
);
// Render component...
}}
>
Load Heavy Component
</button>
</div>
);
}
```

---

## 5. React Suspense for Data Fetching


**Answer:** Suspense enables declarative data loading with fallback UI. Works with resources
that implement "suspensible" interface (throw promise). Experimental feature for data fetching.
Integrates with `[Link]`. SuspenseList coordinates multiple suspending components. Use
with React 18 concurrent features. Libraries like Relay, SWR, React Query implement Suspense
support.

**Code Example:**
```jsx
import { Suspense, useState, unstable_SuspenseList as SuspenseList } from 'react';

// Simple resource implementation


function createResource(promise) {
let status = 'pending';
let result;

const suspensePromise = [Link](


data => {
status = 'success';
result = data;
},
error => {
status = 'error';
result = error;
}
);

return {
read() {
if (status === 'pending') {
throw suspensePromise; // This triggers Suspense
} else if (status === 'error') {
throw result; // Throw error for Error Boundary
} else if (status === 'success') {
return result; // Return data
}
}
};
}

// Data fetching with Suspense


function fetchUser(userId) {
const promise = fetch(`/api/users/${userId}`)
.then(res => [Link]());

return createResource(promise);
}

function fetchPosts(userId) {
const promise = fetch(`/api/users/${userId}/posts`)
.then(res => [Link]());

return createResource(promise);
}

// Components that suspend


function UserProfile({ userId }) {
const user = [Link]();

return (
<div>
<h2>{[Link]}</h2>
<p>{[Link]}</p>
</div>
);
}

function UserPosts({ userId }) {


const posts = [Link]();

return (
<div>
<h3>Posts ({[Link]})</h3>
<ul>
{[Link](post => (
<li key={[Link]}>{[Link]}</li>
))}
</ul>
</div>
);
}

// Parent component
function UserPage({ userId }) {
// Create resources
const userResource = fetchUser(userId);
const postsResource = fetchPosts(userId);
return (
<div>
<Suspense fallback={<div>Loading user...</div>}>
<UserProfile userId={userId} userResource={userResource} />
</Suspense>

<Suspense fallback={<div>Loading posts...</div>}>


<UserPosts userId={userId} postsResource={postsResource} />
</Suspense>
</div>
);
}

// With SuspenseList for coordinated loading


function Dashboard() {
return (
<SuspenseList revealOrder="forwards" tail="collapsed">
<Suspense fallback={<div>Loading stats...</div>}>
<StatsWidget />
</Suspense>

<Suspense fallback={<div>Loading chart...</div>}>


<ChartWidget />
</Suspense>

<Suspense fallback={<div>Loading feed...</div>}>


<ActivityFeed />
</Suspense>
</SuspenseList>
);
}

// Custom hook for Suspense-ready fetching


function useSuspenseQuery(query, variables) {
const [resource, setResource] = useState(() =>
createResource([Link](variables))
);

useEffect(() => {
const newResource = createResource([Link](variables));
setResource(newResource);
}, [query, variables]);

return [Link]();
}

// Component using the hook


function ProductDetails({ productId }) {
const product = useSuspenseQuery(productQuery, { id: productId });

return (
<div>
<h1>{[Link]}</h1>
<p>{[Link]}</p>
<p>Price: ${[Link]}</p>
</div>
);
}

// Error handling with Suspense


function SuspenseWithErrorBoundary({ children, fallback }) {
return (
<ErrorBoundary
fallback={<div>Failed to load. <button>Retry</button></div>}
>
<Suspense fallback={fallback}>
{children}
</Suspense>
</ErrorBoundary>
);
}
```

---

## 6. Concurrent Features (React 18+)


**Answer:** Concurrent React enables interruptible rendering for better user experience.
Features: `startTransition` for non-urgent updates, `useTransition` for pending state,
`useDeferredValue` for deferring updates, Streaming SSR with Suspense. Enables apps to stay
responsive during heavy rendering. Opt-in feature - regular updates remain synchronous.

**Code Example:**
```jsx
import {
useState,
useTransition,
useDeferredValue,
startTransition,
Suspense
} from 'react';

function SearchComponent() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
const [isPending, startTransition] = useTransition();

// Filtered results based on deferred query


const filteredResults = useMemo(() => {
return [Link](item =>
[Link]().includes([Link]())
);
}, [deferredQuery]);

const handleSearch = (newQuery) => {


// Urgent: Update input immediately
setQuery(newQuery);
// Mark state update as non-urgent (transition)
startTransition(() => {
// This update may be interrupted
setSearchResults(filteredResults);
});
};

return (
<div>
<input
value={query}
onChange={(e) => handleSearch([Link])}
placeholder="Search..."
/>

{isPending && <span>Updating results...</span>}

<SearchResults results={filteredResults} />


</div>
);
}

// Using startTransition directly


function TabContainer() {
const [tab, setTab] = useState('home');

function selectTab(nextTab) {
// Urgent: Show tab immediately
setTab(nextTab);

// Non-urgent: Load tab content


startTransition(() => {
setTabContent(loadTabContent(nextTab));
});
}

return (
<div>
<TabButton
isActive={tab === 'home'}
onClick={() => selectTab('home')}
>
Home
</TabButton>
<TabButton
isActive={tab === 'about'}
onClick={() => selectTab('about')}
>
About
</TabButton>

<Suspense fallback={<LoadingSpinner />}>


{tab === 'home' && <HomeTab />}
{tab === 'about' && <AboutTab />}
</Suspense>
</div>
);
}

// useDeferredValue example
function TypeaheadSearch() {
const [text, setText] = useState('');
const deferredText = useDeferredValue(text);

const suggestions = useMemo(() => {


// Expensive filtering operation
return getSuggestions(deferredText);
}, [deferredText]);

return (
<div>
<input
value={text}
onChange={(e) => setText([Link])}
/>

{/* Suggestions update with lower priority */}


<SuggestionsList suggestions={suggestions} />
</div>
);
}

// Streaming SSR with Suspense


function App() {
return (
<html>
<head>
<title>My App</title>
</head>
<body>
<Suspense fallback={<div>Loading navbar...</div>}>
<Navbar />
</Suspense>

<main>
<Suspense fallback={<div>Loading main content...</div>}>
<MainContent />
</Suspense>
</main>

{/* This can stream in separately */}


<Suspense fallback={<div>Loading footer...</div>}>
<Footer />
</Suspense>
</body>
</html>
);
}
// Automatic batching (React 18)
function BatchExample() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);

function handleClick() {
// These updates are batched together
setCount(c => c + 1);
setFlag(f => !f);

// In React 17 and earlier, these would cause two re-renders


// In React 18, they're batched into a single re-render
}

// Also works with timeouts, promises, native event handlers


setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// Batched in React 18
}, 1000);

return (
<div>
<button onClick={handleClick}>
Count: {count}, Flag: {[Link]()}
</button>
</div>
);
}
```

---

## 7. Advanced State Management Patterns


**Answer:** Beyond useState: `useReducer` for complex state logic, Context + `useReducer` for
global state, Zustand/Recoil/Jotai for atomic state, finite state machines (XState), optimistic
updates for better UX. Choose based on app complexity: Context for small apps, Zustand for
medium, Redux for large. Consider data flow, dev tools, middleware needs.

**Code Example:**
```jsx
import { useReducer, createContext, useContext } from 'react';

// useReducer for complex state


const initialState = {
users: [],
loading: false,
error: null,
filters: { role: '', search: '' },
pagination: { page: 1, limit: 10, total: 0 }
};

function userReducer(state, action) {


switch ([Link]) {
case 'FETCH_USERS_REQUEST':
return { ...state, loading: true, error: null };

case 'FETCH_USERS_SUCCESS':
return {
...state,
loading: false,
users: [Link],
pagination: [Link]
};

case 'FETCH_USERS_FAILURE':
return { ...state, loading: false, error: [Link] };

case 'SET_FILTERS':
return {
...state,
filters: { ...[Link], ...[Link] },
pagination: { ...[Link], page: 1 }
};

case 'SET_PAGE':
return { ...state, pagination: { ...[Link], page: [Link] } };

case 'ADD_USER':
return { ...state, users: [[Link], ...[Link]] };

case 'UPDATE_USER':
return {
...state,
users: [Link](user =>
[Link] === [Link] ? [Link] : user
)
};

case 'DELETE_USER':
return {
...state,
users: [Link](user => [Link] !== [Link])
};

default:
return state;
}
}

function UserManager() {
const [state, dispatch] = useReducer(userReducer, initialState);

const fetchUsers = async () => {


dispatch({ type: 'FETCH_USERS_REQUEST' });

try {
const response = await fetch(
`/api/users?page=${[Link]}&limit=${[Link]}`
);
const data = await [Link]();

dispatch({
type: 'FETCH_USERS_SUCCESS',
payload: {
users: [Link],
pagination: [Link]
}
});
} catch (error) {
dispatch({ type: 'FETCH_USERS_FAILURE', payload: [Link] });
}
};

// Context + useReducer pattern


return (
<[Link] value={{ state, dispatch }}>
<UserList />
<UserFilters />
<Pagination />
</[Link]>
);
}

// Optimistic updates pattern


function LikeButton({ postId }) {
const [isLiking, setIsLiking] = useState(false);
const [likes, setLikes] = useState(0);
const [hasLiked, setHasLiked] = useState(false);

const handleLike = async () => {


// Optimistic update
const previousLikes = likes;
const previousHasLiked = hasLiked;

setLikes(prev => hasLiked ? prev - 1 : prev + 1);


setHasLiked(prev => !prev);
setIsLiking(true);

try {
await fetch(`/api/posts/${postId}/like`, {
method: hasLiked ? 'DELETE' : 'POST'
});
} catch (error) {
// Rollback on error
setLikes(previousLikes);
setHasLiked(previousHasLiked);
alert('Failed to update like');
} finally {
setIsLiking(false);
}
};

return (
<button
onClick={handleLike}
disabled={isLiking}
className={hasLiked ? 'liked' : ''}
>
{hasLiked ? 'Unlike' : 'Like'} ({likes})
</button>
);
}

// Finite state machine pattern


function useFetchMachine(url) {
const [state, setState] = useState('idle');
const [data, setData] = useState(null);
const [error, setError] = useState(null);

const transitions = {
idle: { FETCH: 'loading' },
loading: {
SUCCESS: 'success',
ERROR: 'error',
CANCEL: 'idle'
},
success: { FETCH: 'loading', RESET: 'idle' },
error: { RETRY: 'loading', RESET: 'idle' }
};

const transition = (action) => {


const nextState = transitions[state][action];
if (nextState) {
setState(nextState);
}
};

const fetchData = async () => {


transition('FETCH');

try {
const response = await fetch(url);
const result = await [Link]();
setData(result);
transition('SUCCESS');
} catch (err) {
setError([Link]);
transition('ERROR');
}
};

const retry = () => {


transition('RETRY');
fetchData();
};

const reset = () => {


transition('RESET');
setData(null);
setError(null);
};

return {
state,
data,
error,
fetchData,
retry,
reset,
isLoading: state === 'loading',
isSuccess: state === 'success',
isError: state === 'error'
};
}

// Atomic state with Jotai pattern


function createAtom(initialValue) {
let value = initialValue;
const listeners = new Set();

return {
get: () => value,
set: (newValue) => {
value = newValue;
[Link](listener => listener());
},
subscribe: (listener) => {
[Link](listener);
return () => [Link](listener);
}
};
}

function useAtom(atom) {
const [value, setValue] = useState([Link]());

useEffect(() => {
const unsubscribe = [Link](() => {
setValue([Link]());
});

return unsubscribe;
}, [atom]);

const setAtom = useCallback((newValue) => {


[Link](newValue);
}, [atom]);
return [value, setAtom];
}
```

You might also like