0% found this document useful (0 votes)
9 views46 pages

React Fundamentals and Concepts Guide

This document is a comprehensive guide on React JS interview questions and answers, covering various topics such as fundamentals, components, state management, hooks, and best practices. It includes explanations, code snippets, and comparisons with other frameworks, making it a valuable resource for both interview preparation and understanding React concepts. Key sections include an overview of React, JSX, Virtual DOM, props vs. state, and the use of hooks like useState, useEffect, and useContext.

Uploaded by

AJAY A
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)
9 views46 pages

React Fundamentals and Concepts Guide

This document is a comprehensive guide on React JS interview questions and answers, covering various topics such as fundamentals, components, state management, hooks, and best practices. It includes explanations, code snippets, and comparisons with other frameworks, making it a valuable resource for both interview preparation and understanding React concepts. Key sections include an overview of React, JSX, Virtual DOM, props vs. state, and the use of hooks like useState, useEffect, and useContext.

Uploaded by

AJAY A
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

React JS Interview Questions & Answers

Complete Guide with Code Snippets and Explanations

Table of Contents
1. Fundamentals
2. Components and JSX
3. State and Props
4. Hooks
5. Advanced Concepts
6. Performance Optimization
7. State Management
8. Routing and Navigation
9. Testing and Best Practices

SECTION 1: FUNDAMENTALS
Q1: What is React and why is it used?
Answer:
React is a JavaScript library developed by Facebook for building user interfaces with
reusable components. It uses a declarative approach to build UIs efficiently and maintain
application state.

Key Benefits:
Component-Based Architecture: Build encapsulated components that manage their
own state
Virtual DOM: Improves performance by minimizing direct DOM manipulation
Unidirectional Data Flow: Makes application logic predictable and easier to debug
SEO Friendly: Better search engine optimization with server-side rendering support
Large Community: Extensive ecosystem and third-party libraries
Code Example:

import React from 'react';


function App() {
return (
Welcome to React
Building user interfaces made simple

);
}
export default App;

Q2: What is JSX and how does it work?


Answer:
JSX is a syntax extension for JavaScript that allows you to write HTML-like code within
JavaScript. It gets compiled to JavaScript function calls by tools like Babel.
How JSX Works:

JSX is not valid JavaScript; it must be transformed into function calls


JSX elements are converted to [Link]() calls
JSX provides a more readable and intuitive way to describe UI structures
Code Example:
// JSX syntax (what we write)
const element =

Hello, World!
;
// Compiled JavaScript (what browser understands)
const element = [Link]('h1', null, 'Hello, World!');
// JSX with attributes and expressions
const name = 'John';
const element = (

Hello, {name}
Current year: {new Date().getFullYear()}
);
Q3: What is the Virtual DOM and how does it work?
Answer:
The Virtual DOM is an in-memory representation of the real DOM. React uses it to improve
performance by minimizing expensive DOM operations.
How It Works:

1. When a component's state or props change, React creates a new Virtual DOM tree
2. React compares the new Virtual DOM with the previous one (reconciliation)
3. React calculates the minimum number of changes needed (diffing algorithm)
4. React updates only the changed elements in the real DOM (batch updates)
Benefits:
Improves performance by reducing direct DOM manipulations
Provides abstraction layer between application code and browser DOM
Enables efficient rendering of large lists and complex UIs

Code Example:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);

// When count changes, Virtual DOM is updated first


// Then React compares with previous Virtual DOM
// Finally, only the changed <p> element is updated in real DOM
return (
Count: {count}

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


Increment
</button>

);
}
export default Counter;

Q4: What are the differences between React and other frameworks?
Answer:

React differs from frameworks like Angular and Vue in several ways:
Feature React Angular Vue
Type Library Framework Framework
Learning Moderat
Steep Gentle
Curve e
Bundle Size Smaller Larger Smallest
No (Change
Virtual DOM Yes Yes
Detection)
Data Binding One-way Two-way Two-way
Very
Community Large Growing
Large
JavaScrip JavaScript/TypeSc
Language TypeScript
t ript

SECTION 2: COMPONENTS AND JSX


Q5: What are functional and class components? What are the differences?
Answer:

React supports two types of components: functional components and class components.
Functional Components:
JavaScript functions that return JSX
Simpler and more concise
Recommended approach in modern React
Can use hooks for state and side effects

Class Components:
ES6 classes that extend [Link]
More verbose but provide full lifecycle control
Use [Link] and [Link] for state management
Older approach, still supported but less common
Code Example:

// Functional Component
function Welcome(props) {
return
Hello, {[Link]}!
;
}

// With Hooks for state


function Counter() {
const [count, setCount] = useState(0);
return (
Count: {count}

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


Increment
</button>

);
}
// Class Component
class Welcome extends [Link] {
render() {
return

Hello, {[Link]}!
;
}
}
// Class Component with state
class Counter extends [Link] {
constructor(props) {
super(props);
[Link] = { count: 0 };
}
render() {
return (
Count: {[Link]}

<button onClick={() => [Link]({ count: [Link] + 1 })}>


Increment
</button>

);
}
}
Q6: What are fragments and why are they useful?
Answer:
Fragments are a way to group multiple elements without adding extra DOM nodes. They
are useful when a component needs to return multiple elements.
When to Use Fragments:

Returning multiple elements from render method


Creating table rows (tr without tbody wrapper)
Creating list items (li without extra wrapper)
Avoiding unnecessary div wrappers that affect styling
Code Example:
import React from 'react';

// Without Fragment - extra div in DOM


function ListItems() {
return (
Item 1
Item 2
Item 3

);
}
// With Fragment - short syntax
function ListItemsShort() {
return (
<>
Item 1
Item 2
Item 3

</>
);
}
// With Fragment - long syntax (allows key prop)
function ListItemsWithKey() {
const items = ['Item 1', 'Item 2', 'Item 3'];
return (
<>
{[Link]((item, index) => (
<[Link] key={index}>
{item}

</[Link]>
))}
</>
);
}
export default ListItemsShort;

SECTION 3: STATE AND PROPS


Q7: What are props and how do they differ from state?
Answer:
Props and state are both JavaScript objects that influence the output of a component, but
they serve different purposes.

Props (Properties):
Passed from parent to child component
Read-only; child cannot modify props
Used to pass data and functions down the component tree
Component receiving props cannot change them
State:

Managed within the component


Can be modified using setState (class) or setState hook (functional)
Private to the component; not directly accessible to other components
Changes trigger re-render of the component
Code Example:
// Parent Component
function Parent() {
const [parentState, setParentState] = useState('Parent Data');

return (

);
}
// Child Component receiving props
function Child(props) {
const [childState, setChildState] = useState('Child Data');
return (
<div>
Props from Parent:
Name: {[Link]}

Age: {[Link]}
Message: {[Link]}
<h2>Own State:</h2>
<p>State: {childState}</p>
<button onClick={() => setChildState('Updated Child Data')}>
Update State
</button>
</div>

);
}

Q8: What is prop drilling and how can it be avoided?


Answer:
Prop drilling (also called "threading") occurs when you pass props through multiple layers
of components that don't use them, just to pass them to a deeply nested component.

Problems with Prop Drilling:


Makes code harder to maintain and understand
Creates tight coupling between components
Increases props in intermediate components unnecessarily
Difficult to refactor when prop structure changes
Solutions:

1. Context API - Pass data without intermediate props


2. Redux or other state management - Centralized state
3. Component composition - Restructure component hierarchy
Code Example:
// Without Context - Prop Drilling (Bad)
function App() {
const [user, setUser] = useState({ name: 'John', role: 'Admin' });
return ;
}

function Level1({ user }) {


return ;
}
function Level2({ user }) {
return ;
}
function Level3({ user }) {
return
User: {[Link]}
;
}

// With Context - Better (Good)


const UserContext = [Link]();
function App() {
const [user, setUser] = useState({ name: 'John', role: 'Admin' });
return (
<[Link] value={user}>

</[Link]>
);
}
function Level1() {
return ;
}

function Level2() {
return ;
}
function Level3() {
const user = useContext(UserContext);
return

User: {[Link]}
;
}

Q9: What are controlled and uncontrolled components?


Answer:
Controlled and uncontrolled components refer to how form elements handle their state in
React.

Controlled Components:
Form elements are controlled by React state
Value is always in sync with state
React is the "single source of truth"
Recommended approach
Uncontrolled Components:

Form elements manage their own state in DOM


React doesn't control the input value
Uses refs to access DOM values directly
Less predictable but sometimes simpler
Code Example:

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


// Controlled Component
function ControlledForm() {
const [formData, setFormData] = useState({
name: '',
email: ''
});
const handleChange = (e) => {
const { name, value } = [Link];
setFormData({
...formData,
[name]: value
});
};

const handleSubmit = (e) => {


[Link]();
[Link]('Submitted:', formData);
};
return (

{[Link]}
{[Link]} Submit
);
}
// Uncontrolled Component
function UncontrolledForm() {
const nameRef = useRef();
const emailRef = useRef();

const handleSubmit = (e) => {


[Link]();
[Link]('Name:', [Link]);
[Link]('Email:', [Link]);
};
return (

Submit
);
}
SECTION 4: REACT HOOKS
Q10: What is the useState hook and how does it work?
Answer:
useState is a hook that lets functional components manage state. It returns an array with
two elements: the current state value and a function to update it.
Syntax:

const [state, setState] = useState(initialValue);


How It Works:
Takes initial value as argument
Returns array with current value and updater function
Updater function triggers re-render when called
Can have multiple useState calls in one component
State updates are asynchronous and batched

Code Example:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');

return (
<div>

Count: {count}
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<button onClick={() => setCount(count - 1)}>
Decrement
</button>

<h2>Name: {name}</h2>
<input
value={name}
onChange={(e) => setName([Link])}
placeholder="Enter name"
/>
</div>
);
}
// Lazy initialization
function ExpensiveComponent() {
// computeInitialState() runs only once on mount
const [state, setState] = useState(() => computeInitialState());

return
{state}
;
}
function computeInitialState() {
[Link]('Computing initial state...');
return 42;
}
export default Counter;

Q11: What is the useEffect hook and how does it work?


Answer:
useEffect is a hook for performing side effects in functional components. It runs after
render and replaces lifecycle methods like componentDidMount, componentDidUpdate,
and componentWillUnmount.

Syntax:
useEffect(() => {
// side effect logic here
return () => {
// cleanup logic here (optional)
};
}, [dependencies]);
Dependency Array Behavior:

No array: Runs after every render


Empty array []: Runs once after component mounts
With dependencies [dep1, dep2]: Runs when dependencies change
Code Example:
import React, { useState, useEffect } from 'react';

function FetchData() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
// Runs once on mount (like componentDidMount)
let isMounted = true;

const fetchUserData = async () => {


try {
const response = await fetch('[Link]
const result = await [Link]();
if (isMounted) {
setData(result);
setLoading(false);
}
} catch (err) {
if (isMounted) {
setError(err);
setLoading(false);
}
}
};

fetchUserData();

// Cleanup function (like componentWillUnmount)


return () => {
isMounted = false;
};

}, []); // Empty dependency array


if (loading) return
Loading...
;
if (error) return
Error: {[Link]}

;
return
{[Link](data)}
;
}
// Multiple effects for different concerns
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [posts, setPosts] = useState([]);
useEffect(() => {
// Effect 1: Fetch user data when userId changes
fetch(/api/users/${userId})
.then(res => [Link]())
.then(data => setUser(data));
}, [userId]);

useEffect(() => {
// Effect 2: Fetch posts when userId changes
fetch(/api/users/${userId}/posts)
.then(res => [Link]())
.then(data => setPosts(data));
}, [userId]);
return (

{user &&

{[Link]}
}
{[Link] > 0 &&
Posts: {[Link]}

);
}
export default FetchData;

Q12: What is the useContext hook and why is it useful?


Answer:
useContext hook allows you to consume context values without wrapping components in
[Link]. It helps avoid prop drilling by passing data directly to nested
components.
When to Use:

Theming (light/dark mode)


User authentication status
Language/internationalization
Global configuration
Avoiding prop drilling
Code Example:
import React, { createContext, useContext, useState } from 'react';
// Create context
const ThemeContext = createContext();
// Create provider component
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');

const toggleTheme = () => {


setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
};
return (
<[Link] value={{ theme, toggleTheme }}>
{children}
</[Link]>
);
}
// Custom hook for using context
function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within ThemeProvider');
}
return context;
}

// Component consuming context


function Header() {
const { theme, toggleTheme } = useTheme();
return (
<header style={{
background: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#000' : '#fff'
}}>

My App
Switch to {theme === 'light' ? 'dark' : 'light'} mode

</header>
);
}

// App setup
function App() {
return (
);
}
export default App;

Q13: What is the useRef hook and when should you use it?
Answer:
useRef creates a mutable reference object that persists across re-renders. Unlike state,
updating a ref doesn't trigger a re-render.

Use Cases:
Accessing DOM elements directly (focus, text selection)
Storing mutable values that don't affect rendering
Keeping track of timers or intervals
Integrating with third-party libraries
Code Example:

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


function TextInput() {
const inputRef = useRef(null);
const countRef = useRef(0);
const [rerenders, setRerenders] = useState(0);
const focusInput = () => {
[Link]();
};

const handleClick = () => {


[Link] += 1;
[Link]('Clicked', [Link], 'times');
// No re-render triggered
};
const triggerRender = () => {
setRerenders(rerenders + 1);
};
return (
<div>
Focus Input

<button onClick={handleClick}>Count (no re-render)</button>


<p>Ref count: {[Link]}</p>

<button onClick={triggerRender}>
Trigger Re-render (count: {rerenders})
</button>
</div>

);
}

// Storing interval ID
function Timer() {
const intervalRef = useRef(null);
const [seconds, setSeconds] = useState(0);
const startTimer = () => {
[Link] = setInterval(() => {
setSeconds(s => s + 1);
}, 1000);
};
const stopTimer = () => {
clearInterval([Link]);
};

return (
Seconds: {seconds}
Start Stop

);
}
export default TextInput;

Q14: What are custom hooks and how do you create them?
Answer:
Custom hooks are reusable functions that use React hooks internally. They allow you to
extract component logic into reusable functions. A custom hook is a JavaScript function
whose name starts with "use" and may call other hooks.

Rules for Custom Hooks:


Name must start with "use"
Can call other hooks
Can be shared across components
Logic is isolated per component instance
Code Example:

import { useState, useEffect } from 'react';


// Custom Hook: useFetch
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
let isMounted = true;

const fetchData = async () => {


try {
const response = await fetch(url);
if (![Link]) throw new Error('Network response was not ok');
const json = await [Link]();
if (isMounted) {
setData(json);
setLoading(false);
}
} catch (error) {
if (isMounted) {
setError(error);
setLoading(false);
}
}
};

fetchData();

return () => {
isMounted = false;
};

}, [url]);
return { data, loading, error };
}

// Custom Hook: useForm


function useForm(initialValues) {
const [values, setValues] = useState(initialValues);
const handleChange = (e) => {
const { name, value } = [Link];
setValues({
...values,
[name]: value
});
};
const resetForm = () => {
setValues(initialValues);
};

return { values, handleChange, resetForm };


}
// Using custom hooks
function UserProfile() {
const { data: user, loading, error } = useFetch('/api/user');
const { values, handleChange } = useForm({ name: '', email: '' });
if (loading) return
Loading...

;
if (error) return
Error loading user
;
return (

{user?.name}
{[Link]}

);
}
// Custom Hook: useLocalStorage
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 = (value) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
[Link](key, [Link](valueToStore));
} catch (error) {
[Link](error);
}
};
return [storedValue, setValue];
}

export { useFetch, useForm, useLocalStorage };

Q15: What is the useReducer hook and when should you use it?
Answer:

useReducer is an alternative to useState for managing complex state logic. It's useful when
you have multiple state variables that depend on each other or complex state transitions.
Syntax:
const [state, dispatch] = useReducer(reducer, initialState);

When to Use:
Complex state logic with multiple transitions
Multiple related state values
State updates that depend on previous state
Large component state with many interactions
Code Example:

import React, { useReducer } from 'react';


// Reducer function
function counterReducer(state, action) {
switch ([Link]) {
case 'INCREMENT':
return { count: [Link] + 1 };
case 'DECREMENT':
return { count: [Link] - 1 };
case 'RESET':
return { count: 0 };
default:
return state;
}
}
function Counter() {
const initialState = { count: 0 };
const [state, dispatch] = useReducer(counterReducer, initialState);

return (
Count: {[Link]}

<button onClick={() => dispatch({ type: 'INCREMENT' })}>


Increment
</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>
Decrement
</button>
<button onClick={() => dispatch({ type: 'RESET' })}>
Reset
</button>

);
}
// Complex example with multiple fields
const initialState = {
name: '',
email: '',
message: '',
submitted: false
};

function formReducer(state, action) {


switch ([Link]) {
case 'SET_FIELD':
return {
...state,
[[Link]]: [Link]
};
case 'SUBMIT':
return {
...state,
submitted: true
};
case 'RESET':
return initialState;
default:
return state;
}
}
function ContactForm() {
const [state, dispatch] = useReducer(formReducer, initialState);
const handleChange = (e) => {
dispatch({
type: 'SET_FIELD',
field: [Link],
value: [Link]
});
};

const handleSubmit = (e) => {


[Link]();
[Link]('Form submitted:', state);
dispatch({ type: 'SUBMIT' });
};
return (

{[Link]}
{[Link]}
Submit
<button type="button" onClick={() => dispatch({ type: 'RESET' })}>
Reset
</button>
{[Link] &&
Form submitted successfully!

);
}
export default Counter;

SECTION 5: ADVANCED CONCEPTS


Q16: What is the Context API and how do you use it?
Answer:
Context API provides a way to pass data through the component tree without having to
pass props down manually at every level. It's useful for managing global state like themes,
authentication, or user preferences.
Components:

createContext: Creates a context object


Provider: Supplies the value to consuming components
Consumer: Accesses the value (less common now with useContext)
useContext Hook: Modern way to consume context
Code Example:
import React, { createContext, useContext, useState } from 'react';

// Step 1: Create context


const AuthContext = createContext();
// Step 2: Create provider component
function AuthProvider({ children }) {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [user, setUser] = useState(null);
const login = (userData) => {
setIsAuthenticated(true);
setUser(userData);
};
const logout = () => {
setIsAuthenticated(false);
setUser(null);
};

const value = {
isAuthenticated,
user,
login,
logout
};
return (
<[Link] value={value}>
{children}
</[Link]>
);
}
// Step 3: Create custom hook for consuming context
function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within AuthProvider');
}
return context;
}

// Step 4: Use in components


function LoginButton() {
const { isAuthenticated, user, login, logout } = useAuth();
return (

{isAuthenticated ? (
Welcome, {[Link]}!
Logout

):(
<button onClick={() => login({ name: 'John Doe' })}>
Login
</button>
)}

);
}
// App setup
function App() {
return (

);
}
export default App;

Q17: What are Higher-Order Components (HOCs) and how do you create
them?
Answer:
A Higher-Order Component is an advanced pattern for reusing component logic. It's a
function that takes a component and returns a new enhanced component with additional
functionality.

When to Use:
Code reuse and logic abstraction
State abstraction and manipulation
Props manipulation
Adding additional markup
Permission/authentication checks
Code Example:

import React from 'react';


// HOC for authentication
function withAuth(WrappedComponent) {
return function AuthHOC(props) {
const [isAuthenticated, setIsAuthenticated] = [Link](false);

[Link](() => {
// Check if user is authenticated
const checkAuth = async () => {
try {
const response = await fetch('/api/auth/check');
if ([Link]) {
setIsAuthenticated(true);
}
} catch (error) {
[Link]('Auth check failed:', error);
}
};

checkAuth();
}, []);

if (!isAuthenticated) {
return <div>Please log in to access this page</div>;
}

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

};
}

// HOC for theme


function withTheme(WrappedComponent) {
return function ThemeHOC(props) {
const [theme, setTheme] = [Link]('light');

const toggleTheme = () => {


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

return (
<div style={{
background: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#000' : '#fff',
padding: '20px'
}}>
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'dark' : 'light'} mode
</button>
<WrappedComponent theme={theme} {...props} />
</div>
);

};
}

// Original component
function Dashboard(props) {
return (

Dashboard
Theme: {[Link]}

);
}
// Enhanced components
const AuthenticatedDashboard = withAuth(Dashboard);
const ThemedDashboard = withTheme(Dashboard);
const AuthenticatedThemedDashboard = withAuth(withTheme(Dashboard));
export default AuthenticatedThemedDashboard;

Q18: What are React Portals and when are they used?
Answer:
Portals provide a way to render components outside of their parent DOM hierarchy. This is
useful for modals, tooltips, dropdowns, and overlays that need to visually break out of their
parent container.

Use Cases:
Modal dialogs
Dropdowns and tooltips
Loading spinners
Notifications and alerts
Context-aware overlays
Code Example:

import React from 'react';


import ReactDOM from 'react-dom';
// Modal component using Portal
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;
return [Link](
<div style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
background: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 1000
}}>
<div style={{
background: 'white',
padding: '20px',
borderRadius: '8px',
maxWidth: '500px'
}}>
{children}
Close
</div>
</div>,
[Link]
);
}
// Using the Modal Portal
function App() {
const [isModalOpen, setIsModalOpen] = [Link](false);

return (
<div>

My App
<button onClick={() => setIsModalOpen(true)}>
Open Modal
</button>

<Modal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
>
<h2>Modal Title</h2>
<p>This is a modal rendered using Portal</p>
</Modal>
</div>

);
}
export default App;
Q19: What is code splitting and [Link]?
Answer:
Code splitting is a technique to split code into smaller bundles and load them on-demand.
[Link] enables dynamic imports with Suspense for lazy loading components.
Benefits:

Reduces initial bundle size


Improves initial page load time
Components load only when needed
Better performance for large applications
Code Example:
import React, { Suspense, lazy } from 'react';

// Lazy load components


const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
const Profile = lazy(() => import('./pages/Profile'));
function App() {
const [page, setPage] = [Link]('dashboard');
const renderPage = () => {
switch (page) {
case 'dashboard':
return ;
case 'settings':
return ;
case 'profile':
return ;
default:
return ;
}
};

return (
<div>
<button onClick={() => setPage('dashboard')}>Dashboard</button>
<button onClick={() => setPage('settings')}>Settings</button>
<button onClick={() => setPage('profile')}>Profile</button>

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


{renderPage()}
</Suspense>
</div>
);
}
export default App;

// pages/[Link]
function Dashboard() {
return

Dashboard Page
;
}
export default Dashboard;

Q20: What are Error Boundaries and how do you implement them?
Answer:
Error Boundaries are React components that catch JavaScript errors anywhere in the
component tree and display a fallback UI. They help prevent the entire app from crashing.

Limitations:
Only work with class components
Don't catch errors in event handlers (use try-catch)
Don't catch async errors
Don't catch server-side errors
Don't catch errors in the error boundary itself
Code Example:

import React from 'react';


// Error Boundary Component (must be class component)
class ErrorBoundary extends [Link] {
constructor(props) {
super(props);
[Link] = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}

componentDidCatch(error, errorInfo) {
[Link]('Error caught:', error);
[Link]('Error info:', errorInfo);
// You can also log to an error reporting service
}
render() {
if ([Link]) {
return (
<div style={{
padding: '20px',
background: '#ffe0e0',
color: '#c00',
borderRadius: '8px'
}}>

Oops! Something went wrong


{[Link]?.message}

<button onClick={() => [Link]({ hasError: false })}>


Try again
</button>
</div>
);
}

return [Link];

}
}

// Component that might throw error


function ProblematicComponent() {
const [count, setCount] = [Link](0);
if (count > 5) {
throw new Error('Count exceeded maximum value!');
}
return (
Count: {count}

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


Increment
</button>

);
}
// Usage
function App() {
return (
My App

);
}

export default App;

SECTION 6: PERFORMANCE OPTIMIZATION


Q21: What is [Link] and when should you use it?
Answer:

[Link] is a higher-order component that memoizes a component, preventing re-


renders if props haven't changed. It only performs shallow comparison of props.
When to Use:
Preventing unnecessary re-renders of child components
Components with expensive render logic
Components receiving same props frequently
Pure components with no side effects

Code Example:
import React from 'react';
// Without [Link] - re-renders every time parent renders
function ProductCard(props) {
[Link]('ProductCard rendering:', [Link]);
return (
<div style={{ border: '1px solid #ccc', padding: '10px' }}>
{[Link]}
Price: ${[Link]}

</div>
);
}
// With [Link] - only re-renders if props change
const MemoizedProductCard = [Link](ProductCard);
// Custom comparison function
const CustomMemoProductCard = [Link](
ProductCard,
(prevProps, nextProps) => {
return [Link] === [Link] && [Link] === [Link];
}
);
function App() {
const [count, setCount] = [Link](0);

return (
<div>
Count: {count}

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

{/* This will not re-render unless props change */}


<MemoizedProductCard id={1} name="Laptop" price={999} />
<MemoizedProductCard id={2} name="Phone" price={699} />
</div>

);
}
export default App;

Q22: What are useMemo and useCallback hooks?


Answer:
useMemo and useCallback are hooks for performance optimization. They memoize values
and functions to prevent unnecessary recalculations and re-creations.
useMemo:

Memoizes a computed value


Prevents expensive calculations on every render
Returns memoized value
useCallback:
Memoizes a function
Prevents function re-creation on every render
Useful when passing callbacks to memoized child components

Code Example:
import React, { useMemo, useCallback, useState } from 'react';
function ExpensiveCalculation() {
const [count, setCount] = useState(0);
const [items, setItems] = useState([1, 2, 3, 4, 5]);
// Without useMemo - recalculates every render
// const total = [Link]((sum, item) => sum + item, 0);
// With useMemo - calculates only when items change
const total = useMemo(() => {
[Link]('Calculating total...');
return [Link]((sum, item) => sum + item, 0);
}, [items]);

// Without useCallback - new function created every render


// const handleAddItem = () => {
// setItems([...items, [Link]()]);
// };
// With useCallback - same function reference unless dependencies change
const handleAddItem = useCallback(() => {
[Link]('Adding item...');
setItems(prevItems => [...prevItems, [Link]()]);
}, []);
return (
Count: {count}

Total: {total}

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


Increment Count
</button>
Add Item

);
}
// Child component wrapped with [Link]
const ItemList = [Link](function ItemList({ items, onAddItem }) {
[Link]('ItemList rendering');
return (
Items: {[Link]}
Add from child

);
});
export default ExpensiveCalculation;
Q23: What are performance optimization best practices?
Answer:
Key performance optimization techniques:
1. Code Splitting and Lazy Loading
2. Memoization ([Link], useMemo, useCallback)
3. Virtual list rendering (react-window)
4. Avoiding inline functions and objects
5. Proper use of keys in lists
6. Avoiding unnecessary state
7. Using production builds
8. Profiling with React DevTools

Code Example:
import React, { useState, useCallback, useMemo } from 'react';
import { FixedSizeList as List } from 'react-window';
// Bad: Inline function and object
function BadOptimization() {
const [items, setItems] = useState([]);

return (
<div>
{/* Creates new function every render */}
<button onClick={() => [Link]('clicked')}>
Click me
</button>

{/* Creates new style object every render */}


<div style={{ color: 'red', fontSize: '16px' }}>
Styled div
</div>
</div>

);
}

// Good: Memoized function and style


function GoodOptimization() {
const [items, setItems] = useState([]);
// Memoized callback
const handleClick = useCallback(() => {
[Link]('clicked');
}, []);
// Memoized style object
const divStyle = useMemo(() => ({
color: 'red',
fontSize: '16px'
}), []);
return (
Click me
Styled div

);
}

// Virtual list for large datasets


function VirtualList() {
const items = [Link]({ length: 1000 }, (_, i) => Item ${i});
const Row = ({ index, style }) => (

{items[index]}

);
return (

{Row}

);
}

// Proper key usage in lists


function ProperKeyUsage() {
const [items, setItems] = useState([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
]);
return (

{[Link](item => (
// Use stable unique identifier, not index
{[Link]}

))}

);
}

export default GoodOptimization;


SECTION 7: STATE MANAGEMENT
Q24: What is Redux and how does it work?
Answer:
Redux is a state management library that provides a centralized store for application state.
It uses actions, reducers, and a single immutable store to manage state predictably.
Core Concepts:

Store: Single source of truth containing app state


Actions: Objects describing what happened
Reducers: Pure functions that return new state
Dispatch: Method to send actions to reducers
Selectors: Functions to access specific state slices
Code Example:
import { createStore } from 'redux';

// Action types
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
const RESET = 'RESET';
// Action creators
const increment = () => ({ type: INCREMENT });
const decrement = () => ({ type: DECREMENT });
const reset = () => ({ type: RESET });
// Reducer
const initialState = { count: 0 };

function counterReducer(state = initialState, action) {


switch ([Link]) {
case INCREMENT:
return { count: [Link] + 1 };
case DECREMENT:
return { count: [Link] - 1 };
case RESET:
return { count: 0 };
default:
return state;
}
}
// Create store
const store = createStore(counterReducer);
// Subscribe to changes
[Link](() => {
[Link]('State:', [Link]());
});
// Dispatch actions
[Link](increment()); // count: 1
[Link](increment()); // count: 2
[Link](decrement()); // count: 1
[Link](reset()); // count: 0

// React integration example


import React from 'react';
import { Provider, useSelector, useDispatch } from 'react-redux';
function Counter() {
const count = useSelector(state => [Link]);
const dispatch = useDispatch();
return (
Count: {count}

<button onClick={() => dispatch(increment())}>+</button>


<button onClick={() => dispatch(decrement())}>-</button>
<button onClick={() => dispatch(reset())}>Reset</button>

);
}
function App() {
return (

);
}
export default App;

Q25: What is the difference between Redux and Context API?


Answer:
Both Redux and Context API manage state, but they serve different purposes and have
different trade-offs.
Feature Redux Context API
Setup More boilerplate Simpler setup
Better for small-medium
Scale Better for large apps
apps
Performanc Can cause unnecessary re-
Optimized with selectors
e renders
Excellent time-travel
DevTools No built-in DevTools
debugging
Powerful middleware
Middleware No middleware support
system
Learning
Steeper Gentler
Curve
Bundle Size Larger Smaller
Async
Thunks, Sagas Manual handling
Handling

When to Use Redux:


Complex state management
Multiple components accessing same state
Frequent state updates
Need for time-travel debugging
Large production applications

When to Use Context API:


Simple state management
Avoiding prop drilling
Theming and configuration
Small to medium applications
Learning React state management

SECTION 8: TESTING IN REACT


Q26: How do you test React components?
Answer:
Testing React components involves unit tests, integration tests, and snapshot tests.
Common tools include Jest and React Testing Library.
Testing Best Practices:
Test user behavior, not implementation details
Use React Testing Library for user-centric tests
Avoid testing internal state directly
Use meaningful assertions
Mock external dependencies
Test accessibility attributes
Code Example:

// Example component to test


import React, { useState } from 'react';
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const handleSubmit = (e) => {
[Link]();

if (!email || !password) {
setError('Both fields are required');
return;
}

if (![Link]('@')) {
setError('Invalid email format');
return;
}

[Link]('Form submitted:', { email, password });


setError('');

};
return (

<input
type="email"
value={email}
onChange={(e) => setEmail([Link])}
placeholder="Enter email"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword([Link])}
placeholder="Enter password"
/>
{error && <p style={{ color: 'red' }}>{error}</p>}
Login
);
}
export default LoginForm;

// Test file
import { render, screen, fireEvent } from '@testing-library/react';
import LoginForm from './LoginForm';
describe('LoginForm Component', () => {
test('renders login form', () => {
render();
expect([Link]('Enter email')).toBeInTheDocument();
expect([Link]('Enter password')).toBeInTheDocument();
expect([Link]('button', { name: /login/i })).toBeInTheDocument();
});
test('shows error when fields are empty', () => {
render();
const submitButton = [Link]('button', { name: /login/i });
[Link](submitButton);
expect([Link]('Both fields are required')).toBeInTheDocument();
});

test('shows error for invalid email', () => {


render();
const emailInput = [Link]('Enter email');
const passwordInput = [Link]('Enter password');
const submitButton = [Link]('button', { name: /login/i });

[Link](emailInput, { target: { value: 'invalidemail' } });


[Link](passwordInput, { target: { value: 'password123' } });
[Link](submitButton);

expect([Link]('Invalid email format')).toBeInTheDocument();

});

test('submits form with valid data', () => {


const consoleSpy = [Link](console, 'log');
render();
const emailInput = [Link]('Enter email');
const passwordInput = [Link]('Enter password');
const submitButton = [Link]('button', { name: /login/i });
[Link](emailInput, { target: { value: 'test@[Link]' } });
[Link](passwordInput, { target: { value: 'password123' } });
[Link](submitButton);

expect(consoleSpy).toHaveBeenCalledWith('Form submitted:', {
email: 'test@[Link]',
password: 'password123'
});

[Link]();

});
});

SECTION 9: BEST PRACTICES AND TIPS


Q27: What are React best practices?
Answer:
Best practices for writing maintainable and efficient React code:

1. Component Structure:
Keep components small and focused
Single Responsibility Principle
Clear naming conventions
2. State Management:
Lift state only when necessary
Keep state as local as possible
Use Context API or Redux for shared state
3. Performance:
Use [Link] for pure components
Implement proper key prop in lists
Lazy load components and routes
Avoid unnecessary re-renders
4. Code Quality:
Write meaningful comments
Use PropTypes or TypeScript
Follow consistent code style
Regular code reviews
5. Accessibility:
Use semantic HTML
ARIA labels where needed
Keyboard navigation support
Test with accessibility tools
Code Example:
import React, { useState, useCallback, memo } from 'react';
import PropTypes from 'prop-types';

// Best practice: Small, focused component


const TodoItem = memo(function TodoItem({ todo, onToggle, onDelete }) {
const handleToggle = useCallback(() => {
onToggle([Link]);
}, [[Link], onToggle]);
return (
<li
style={{
textDecoration: [Link] ? 'line-through' : 'none'
}}
role="listitem"
aria-label={Todo: ${[Link]}}
>
<input
type="checkbox"
checked={[Link]}
onChange={handleToggle}
aria-label={Complete ${[Link]}}
/>
{[Link]}
<button
onClick={() => onDelete([Link])}
aria-label={Delete ${[Link]}}
>
Delete
</button>
</li>
);
});
// PropTypes for type checking
[Link] = {
todo: [Link]({
id: [Link],
title: [Link],
completed: [Link]
}).isRequired,
onToggle: [Link],
onDelete: [Link]
};

// Parent component
function TodoList() {
const [todos, setTodos] = useState([
{ id: 1, title: 'Learn React', completed: false },
{ id: 2, title: 'Build project', completed: false }
]);
const handleToggle = useCallback((id) => {
setTodos(prevTodos =>
[Link](todo =>
[Link] === id ? { ...todo, completed: ![Link] } : todo
)
);
}, []);

const handleDelete = useCallback((id) => {


setTodos(prevTodos => [Link](todo => [Link] !== id));
}, []);
return (

My Todo List
{[Link](todo => (

))}

);
}
export default TodoList;

Q28: How do you handle errors and exceptions in React?


Answer:
Error handling in React involves multiple strategies depending on error type and location.
Strategies:

1. Error Boundaries: For render errors


2. Try-Catch: For event handlers
3. [Link](): For async operations
4. useEffect cleanup: For preventing memory leaks
5. Error logging: Send errors to monitoring service
Code Example:
import React, { useState, useEffect } from 'react';

// Error Boundary for render errors


class ErrorBoundary extends [Link] {
constructor(props) {
super(props);
[Link] = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}

componentDidCatch(error, errorInfo) {
// Log to error reporting service
logErrorToService(error, errorInfo);
}
render() {
if ([Link]) {
return

Something went wrong:


{[Link]?.message}
;
}
return [Link];
}
}

// Handle errors in event handlers


function FormSubmit() {
const [error, setError] = useState(null);
const handleSubmit = async (e) => {
[Link]();
try {
const response = await fetch('/api/submit', { method: 'POST' });
if (![Link]) throw new Error('Submission failed');
const data = await [Link]();
[Link]('Success:', data);
} catch (err) {
setError([Link]);
logErrorToService(err);
}
};
return (

{error && <p style={{ color: 'red' }}>{error}</p>}


Submit
);
}

// Handle errors in async operations


function DataFetch() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
let isMounted = true;

const fetchData = async () => {


try {
const response = await fetch('/api/data');
if (![Link]) throw new Error('Failed to fetch');
const json = await [Link]();
if (isMounted) setData(json);
} catch (err) {
if (isMounted) {
setError(err);
logErrorToService(err);
}
}
};

fetchData();

return () => {
isMounted = false;
};

}, []);
if (error) return
Error: {[Link]}

;
if (!data) return
Loading...
;
return
{[Link](data)}
;
}
// Helper function
function logErrorToService(error, errorInfo) {
[Link]('Error logged:', error);
// Send to error tracking service (Sentry, LogRocket, etc.)
}
export { ErrorBoundary, FormSubmit, DataFetch };

CONCLUSION
This comprehensive guide covers:

React fundamentals and core concepts


Component patterns and best practices
Hooks and their usage
Advanced features like Context API and Portals
Performance optimization techniques
State management approaches
Testing strategies
Error handling
Production-ready practices
Regular practice with these concepts and patterns will prepare you well for React
interviews at all levels.

Key Takeaways
1. Master hooks: useState, useEffect, useContext, useRef, useReducer
2. Understand component lifecycle and rendering
3. Know when to use Context API vs Redux
4. Implement proper error handling
5. Optimize performance proactively
6. Write testable and accessible components
7. Follow best practices consistently
8. Keep components focused and reusable
9. Think in terms of user behavior, not implementation
10. Stay updated with React ecosystem changes

You might also like