ReactJS Begineer to Advance Concept
ReactJS Begineer to Advance Concept
● Component-Based Architecture:
● Virtual DOM
● Unidirectional Data Flow
● JSX Syntax
Uses of React:
2. What is the difference between React and other JavaScript frameworks like
Angular or Vue?
When to use Best for SPAs, dynamic UIs, Ideal for large,
and when flexibility is needed. enterprise-level
applications.
10
3. What are the advantages and limitations of using React?
Limitations:-
● React often requires additional libraries for state management, routing, or form
handling, which can lead to a higher setup complexity.
● Many third-party libraries in the React ecosystem may have inadequate
documentation or inconsistent quality.
● React relies heavily on external libraries for functionalities like state management
(e.g., Redux, MobX) or server-side rendering (e.g., Next.js).
● React applications that rely solely on client-side rendering can have SEO issues
unless tools like Next.js are used for server-side rendering.
In React, the Virtual DOM (VDOM) serves as this blueprint for your user interface.
● When your React component renders for the first time, React creates a virtual
DOM, a lightweight JavaScript object representation of the actual DOM.
● This virtual DOM is a copy of the real DOM, but it exists entirely in memory.
● Whenever a state or prop changes in your component, React re-renders the
component, creating a new virtual DOM.
● React's efficient diffing algorithm compares the old virtual DOM with the new one,
identifying the minimal set of changes required to update the real DOM.
● This process is highly optimized to minimize the number of DOM manipulations
11
Real-World Example
Imagine you want to update a list of 100 items in the Real DOM:
● Without optimization, the browser may re-render the entire list, even if only one
item changes.
● React detects that only one item's content has changed, updates it in the Virtual
DOM, and applies just that change to the Real DOM.
Performance Optimization:
In essence, the virtual DOM acts as a layer of abstraction between your React
components and the actual DOM, enabling efficient and performant UI updates.
JSX (JavaScript XML) is a syntax extension for JavaScript that allows developers to
write HTML-like code directly within JavaScript.
JSX is not a requirement for React, but it makes code more readable and expressive.
Importance of JSX
JSX allows you to write HTML-like code within JavaScript. This makes it easier to
visualize the UI components directly in the logic where they're created.
12
Since JSX is embedded in JavaScript, you can seamlessly integrate JavaScript
expressions within your UI code.
JSX is not valid JavaScript—it must be transpiled (converted) into standard JavaScript
before execution.
<div>
<h1>Hello, {name}!</h1>
</div>
is transpiled to:
React.createElement('div', null,
);
Features of JSX
1. Embedding Expressions:
○
2. Attributes:
3. Conditional Rendering:
13
Use expressions for conditional rendering:
<p>{isLoggedIn ? 'Welcome back!' : 'Please log in.'}</p>
○
4. Styling:
5. Nested Components:
<Footer />
Advantages of JSX
Limitation:
● JSX must be transpiled using tools like Babel, adding a build step to the workflow.
● Deeply nested components or complex UIs can make JSX verbose and harder to
read.
6. Can browsers read JSX directly? If not, how is it converted?
JSX Code:
<div>
<h1>Hello, World!</h1>
</div>
);
};
return React.createElement(
'div',
null,
);
};
React.createElement:
a. This function creates a JavaScript object representing the Virtual DOM node.
b. The object includes the element type ('div' or 'h1'), any attributes (null in this
case), and child nodes (Hello, World!).
1. Babel:
○ Babel is the most commonly used tool for transpiling JSX into JavaScript.
○ It uses a preset like @babel/preset-react to understand JSX syntax.
15
Example Babel Configuration:
json
Copy code
{
"presets": ["@babel/preset-react"]
2. Build Tools:
○ Tools like Webpack, Vite, or Parcel integrate Babel to handle JSX during the build
process.
3. CDN-Based Transpilation:
○ For simple projects, tools like esbuild or online CDNs (e.g., Babel Standalone) can
transpile JSX directly in the browser (not recommended for production).
Development Mode:
c. Tools like React Scripts (from Create React App) handle this automatically using
Babel and Webpack.
Production Mode:
● Functional Components
● Class Components
Functional components are JavaScript functions that accept props (inputs) and return
React elements describing what should appear on the UI.
Introduced Features:
};
Key Features:
Class components are ES6 classes that extend React.Component. They must include a
render() method, which returns the React elements to display.
render() {
Key Features:
A pattern in React where a function takes a component and returns a new component
with additional features.
console.log('Props:', props);
};
};
Controlled Example:
};
The key differences between functional components and class components in React lie
in their syntax, features, and usage. Here's a detailed comparison:
1. Syntax
Functional Components:
Example:
Class Components:
render() {
2. State Management
Functional Components:
● Originally stateless but gained the ability to manage state with React Hooks
(introduced in React 16.8).
● Use useState and useReducer hooks to manage state.
Example:
function Counter() {
return (
<div>
<p>Count: {count}</p>
21
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
Class Components:
Example:
constructor(props) {
super(props);
this.state = { count: 0 };
increment = () => {
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
22
<button onClick={this.increment}>Increment</button>
</div>
);
3. Lifecycle Methods
Functional Components:
function App() {
React.useEffect(() => {
console.log('Component Mounted');
return () => {
};
}
23
Class Components:
Example:
function App() {
React.useEffect(() => {
console.log('Component Mounted');
return () => {
};
4. Performance
● Functional Components:
○ Slightly more performant because they don't require the overhead of the this
keyword or binding methods.
○ Easier to optimize with React.memo for memoization.
● Class Components:
○ Slightly less performant due to the use of this and more complex structure.
24
● Functional Components:
● Functional Components:
○ More verbose.
○ Requires additional boilerplate for constructors, method binding, etc.
Signature of React.createElement()
● type: The type of the element (e.g., a string for built-in DOM elements like div or h1,
or a React component).
● props: An object containing the element's properties/attributes (e.g., id,
className, onClick).
● children: The child elements or content inside the element.
Example
JSX Code:
const element = (
Click Me!
</button>
);
Transpiled Code:
'Click Me!'
);
● Type: 'button'
11. What are props in React? How are they different from state?
In React, props (short for "properties") and state are core concepts for managing and
passing data in components.
Props are read-only data passed from a parent component to a child component.
They are used to configure the child component and make it reusable by providing
dynamic values.
Props are typically used to display dynamic data or customize a child component's
behavior.
function Greeting(props) {
}
27
function App() {
State is used to store data that needs to change over time or in response to user actions.
function Counter() {
return (
<div>
<p>Count: {count}</p>
</div>
);
12. How do you pass data from a parent component to a child component?
To pass data from a parent component to a child component in React, you use props.
28
Props allow you to send any data (like strings, numbers, arrays, objects, or functions)
Parent Component:
function Parent() {
return (
<div>
</div>
);
Child Component:
function Child(props) {
return (
<div>
<p>{props.greeting}</p>
</div>
);
29
}
When the state of a component changes, React automatically re-renders the component
to reflect the updated state.
e.preventDefault();
setItems([...items, objItem]);
30
};
setNames(data);
};
return (
<div>
<form onSubmit={handleSubmit}>
</form>
<ul>
{items.map((item) => (
<li key={item.id}>
</li>
))}
</ul>
</div>
);
31
}
React provides two ways to handle form inputs: controlled components and
uncontrolled components. These approaches determine how the form data is managed
and accessed.
1. Controlled Components
In controlled components, the form data is managed by React's state. The component
takes full control of the input element's value using state and updates it through event
handlers like onChange.
Key Features
Example:
function ControlledInput() {
};
32
const handleSubmit = (e) => {
e.preventDefault();
alert(`Name: ${name}`);
};
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
Pros:
Cons:
In uncontrolled components, the form data is managed by the DOM itself. React
interacts with the DOM to retrieve the value when needed, usually via a ref.
Key Features
Example:
function UncontrolledInput() {
e.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
34
</form>
);
Pros:
1. Simpler to implement for basic forms where real-time validation or updates aren't
needed.
2. Useful for integrating with non-React libraries that directly manipulate the DOM.
Cons:
Key Differences
Performanc Can be slower for many inputs. Generally faster, less React
e overhead.
● For simple forms where you only need the value at submission.
● When working with third-party libraries that manipulate the DOM directly.
● For legacy codebases that rely on direct DOM access.
15. Can props be modified inside a child component? Why or why not?
36
No, props cannot be modified inside a child component in React. This is because
props are read-only and are passed down from the parent component to the child
component.
16. One-Way Data Flow: React follows a one-way data flow, where data is passed
from the parent component to the child component via props. The child component can
only receive and read the props but should not modify them. If a child component were
able to modify its props, it would break the unidirectional data flow, leading to
unpredictable behavior and making the app harder to maintain and debug.
17. Immutability of Props: React treats props as immutable, meaning they are not
intended to be changed by the receiving component. The parent component has control
over the props and can modify them by re-rendering and passing updated props down to
the child.
18. State vs. Props: If you need to modify data within a child component, you should
use state instead of props. State is mutable and can be updated within the component.
If the child component needs to modify data and communicate changes back to the
parent, it can do so by calling a function passed from the parent via props (a "callback
function").
19. What happens if you try to update the state directly in React?
If you try to update the state directly in React, it can lead to unexpected behavior and
bugs. React state is designed to be immutable, meaning it should not be modified
directly. Instead, state should always be updated using the state updater function
(setState in class components or the setter function from useState in functional
components).
React Lifecycle
React lifecycle methods are special functions in React components that allow you to
hook into different stages of a component's lifecycle.
These methods are used to initialize components, manage updates, and clean up before
the component is removed from the DOM.
● componentWillUnmount():
○ Invoked just before a component is destroyed.
○ Used to clean up resources like event listeners, timers, or subscriptions.
● static getDerivedStateFromError(error):
39
○ Used to update the state when an error is caught in a child component.
● componentDidCatch(error, info):
○ Used to log errors or display fallback UI.
Modern React applications increasingly rely on functional components and hooks for
managing lifecycle-related tasks.
These lifecycle methods are part of React's class components and are used to handle
side effects and cleanup tasks.
1. componentDidMount()
This method is called once immediately after the component is added to the DOM
(mounted). It is often used for initialization tasks that require the DOM or external data.
● Fetching Data from an API: To retrieve data and populate the component's state.
40
● Setting Up Subscriptions: Adding event listeners, like window.addEventListener
or subscribing to real-time data streams.
● Updating DOM or Third-Party Integrations: Initializing libraries, animations, or
manipulating the DOM.
● Triggering Side Effects: Starting timers, logging analytics, or performing other
one-time setup tasks.
Example:
jsx
Copy code
componentDidMount() {
fetch('https://api.example.com/data')
render() {
2. componentWillUnmount()
This method is called once just before the component is removed from the DOM
(unmounted). It is used to clean up resources to avoid memory leaks.
Example
intervalId = null;
42
componentDidMount() {
console.log('Timer tick');
}, 1000);
componentWillUnmount() {
clearInterval(this.intervalId);
render() {
Without the render() method, React cannot generate the virtual DOM or perform
reconciliation.
44
import React, { Component } from 'react';
render() {
In class components, side effects are handled using lifecycle methods. Side effects are
operations that affect something outside the scope of the function, such as API calls,
DOM manipulations, or setting up subscriptions.
Use the componentDidMount() lifecycle method for side effects that should occur after
the component is added to the DOM.
componentDidMount() {
fetch('https://api.example.com/data')
.then((data) => {
console.log(data);
});
window.addEventListener('resize', this.handleResize);
handleResize = () => {
console.log('Window resized');
};
render() {
In functional components, the useEffect Hook is used to handle all these side effects,
making it more flexible and concise. Here's an equivalent example:
useEffect(() => {
fetch(`https://api.example.com/user/${userId}`)
// Cleanup effect
return () => {
console.log('Cleanup resources');
};
React Hooks
React Hooks are special functions introduced in React 16.8 that allow developers to use
state and other React features in functional components.
They enable functional components to mimic the behavior of class components, such as
managing state, handling side effects, and accessing the lifecycle methods, without
writing a class.
Hooks were introduced to address several challenges and limitations in React's class
components and to enhance the overall developer experience. Here are the key reasons:
Before hooks, functional components were stateless. To manage state or access lifecycle
methods, developers had to use class components, which could be verbose and harder to
read for simple logic.
With Hooks: Hooks enable stateful logic and side effects directly in functional
components, making them more powerful and reusable.
function Counter() {
return (
<div>
<p>Count: {count}</p>
</div>
);
With Hooks: Hooks remove the need for classes entirely, simplifying the learning curve
and codebase.
In class components, it was difficult to reuse stateful logic across multiple components.
Developers often resorted to:
With Hooks: Hooks allow developers to extract reusable logic into custom hooks,
making it cleaner and easier to share across components.
function useFetch(url) {
useEffect(() => {
fetch(url)
}, [url]);
return data;
function App() {
}
50
Advantages of Hooks
Limitations of Hooks
● Learning Curve: While simpler in many ways, hooks introduce new concepts like
dependency arrays in useEffect that can be confusing.
● Overuse of Custom Hooks: Excessive abstraction with hooks can lead to unclear
code.
● Debugging Challenges: Tracking hook behavior can sometimes be more complex,
especially with nested hooks or dependency array issues.
The useState Hook is a built-in React function that allows functional components to
manage state.
Purpose of useState
32. Store Data: It stores and tracks the state of a component, such as user input,
toggles, counters, etc.
33. Trigger Re-renders: When the state is updated via the setter function, React
automatically re-renders the component to reflect the updated state.
51
34. Simplify State Management: Eliminates the need for class components to
manage state, making functional components more powerful and concise.
Syntax of useState
Advantages of useState
Both useEffect and useLayoutEffect are React hooks that allow you to perform side
effects in functional components. However, they differ in timing and use cases.
Timing of Execution
● useEffect: Runs after the browser has painted the screen. This makes it
asynchronous with respect to rendering, so it does not block the UI update.
● useLayoutEffect: Runs synchronously after DOM mutations but before the
browser paints. This means it blocks the browser from updating the screen until the
effect is executed.
2. Use Case
● useEffect:
52
○ Ideal for tasks that don't require blocking the DOM rendering, such as:
■ Fetching data from an API.
■ Subscribing to or cleaning up event listeners.
■ Running analytics or logging.
○ It ensures smoother user experiences since it doesn't delay the browser's paint.
● useLayoutEffect:
○ Useful when you need to read and write layout information (synchronously)
after a render, such as:
■ Measuring DOM elements (e.g., dimensions or positions).
■ Performing animations.
■ Making updates that must happen before the browser paints to avoid visual
flickering.
3. Performance Impact
● useEffect:
○ Non-blocking, so it doesn't negatively impact performance or cause layout
thrashing.
○ Recommended for most side effects.
● useLayoutEffect:
○ Can block rendering if overused, leading to potential performance issues.
○ Use sparingly for critical DOM updates that must happen synchronously.
40. useEffect:
a. Does not execute during server-side rendering because it's designed to run after
rendering is complete.
41. useLayoutEffect:
a. Triggers a warning if used in server-side rendering because it depends on the DOM
being available, which is not the case in SSR environments.
53
Using useEffect for API Fetching
function DataFetcher() {
useEffect(() => {
fetch('https://api.example.com/data')
42. What is the useRef hook, and when would you use it?
The useRef hook in React is a built-in hook that returns a mutable object called a "ref"
that persists across re-renders.
54
It can hold a reference to a DOM element or any mutable value, and it does not trigger a
re-render when the value changes.
initialValue: The value that the ref will be initialized with (optional).
● Persistent reference: The ref object persists across renders. This means you can
store a value that doesn't change between renders without triggering a re-render.
● Does not cause re-renders: Updating the current property of a ref object does
not trigger a re-render of the component.
● Access DOM elements: Can be used to reference and manipulate DOM nodes
directly, similar to React.createRef() in class components.
useRef is frequently used to store references to DOM elements, so you can interact with
them directly without needing to rely on state or props.
function FocusInput() {
return (
<div>
</div>
);
The useContext hook allows components to "subscribe" to the context and retrieve its
current value.
44. What is the useReducer hook, and how is it different from useState?
The useReducer hook in React is a powerful tool for managing state, especially when
the state logic is complex or involves multiple sub-values
45. Reducer Pattern: useReducer uses a reducer function, which determines how the
state should change in response to an action.
46. State and Dispatch: It returns a state variable and a dispatch function. The
dispatch function is used to send an action to the reducer, which updates the state.
47. Scalability: It's well-suited for applications where the state transitions are
complex or involve multiple steps or conditions.
reducer: A function that takes the current state and an action as arguments and returns
the new state.
Example of useReducer
const initialState = 0;
switch (action.type) {
57
case "increment":
return state + 1;
case "decrement":
return state - 1;
case "reset":
return initialState;
default:
function Counter() {
return (
<div>
<p>Count: {count}</p>
);
Custom hooks in React are reusable JavaScript functions that encapsulate logic built
using React hooks (useState, useEffect, useReducer, etc.)
They allow you to extract and share stateful logic between components, making your
code more modular, readable, and maintainable.
Custom hooks always start with the prefix use (e.g., useCustomHook). This naming
convention is necessary because React relies on it to ensure that the rules of hooks are
followed (like only calling hooks at the top level or within a React function component).
49. Reusability: Share logic across multiple components without duplicating code.
50. Clean Code: Separate complex logic from the component, keeping it more
readable.
51. Abstraction: Encapsulate logic into a custom hook, hiding its internal
implementation.
Syntax
A custom hook is essentially a function that can call other hooks. Here's a simple
template:
function useCustomHook() {
useFetch
function useFetch(url) {
useEffect(() => {
try {
setData(result);
} catch (err) {
setError(err.message);
} finally {
60
setLoading(false);
};
fetchData();
function App() {
return (
<div>
<h1>Posts</h1>
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
useToggle
Using useToggle
function App() {
return (
<div>
<button onClick={toggleVisibility}>
</button>
</div>
);
63
}
React Hooks are special functions that allow you to use state and lifecycle features in
functional components. To ensure they work as intended, React enforces a set of rules
for using hooks. These rules help prevent bugs and maintain predictable behavior in your
components.
Rules of Hooks
// Correct
function MyComponent() {
if (count > 5) {
return <div>{count}</div>;
// Incorrect
function MyComponent() {
64
if (someCondition) {
// Correct
function useCustomHook() {
// Incorrect
function regularFunction() {
● React relies on the order of Hook calls to associate state and effects with
components. Violating these rules can lead to unpredictable behavior and runtime errors.
65
Using the eslint-plugin-react-hooks Linter
"plugins": ["react-hooks"],
"rules": {
Event Handling
32. How do you handle events in React? How is it different from plain JavaScript?
n React, handling events is slightly different from handling events in plain JavaScript
due to React's use of a virtual DOM and JSX syntax. Here's a detailed breakdown:
// React
// Plain JavaScript/HTML
Event Handlers
● In React, you pass a function reference to the event handler rather than a string of
JavaScript code.
// React
function handleClick() {
console.log("Button clicked");
// Plain JavaScript
function handleClick(event) {
// React
function handleSubmit(event) {
event.preventDefault();
console.log("Form submitted");
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>;
Passing Arguments
68
● To pass arguments to an event handler, use an arrow function or the .bind
method
function handleClick(id) {
// Using .bind
In React, a Synthetic Event is a wrapper around the native DOM event system that
ensures events are consistent and cross-browser compatible. It is part of React's event
system, which abstracts away differences in how browsers handle events to provide a
uniform API.
function App() {
function handleClick(event) {
Event Pooling
React reuses synthetic event objects to improve performance. However, this means you
cannot access event properties asynchronously unless you call event.persist().
Without event.persist()
function App() {
function handleClick(event) {
console.log(event.type); // "click"
setTimeout(() => {
70
console.log(event.type); // Error: Properties are nullified
}, 1000);
With event.persist()
function App() {
function handleClick(event) {
console.log(event.type); // "click"
setTimeout(() => {
console.log(event.type); // "click"
}, 1000);
}
71
In React, you can pass arguments to event handlers by wrapping the event handler
function in another function (commonly using an arrow function) or by using the
.bind() method. Here's a detailed explanation of both approaches
An arrow function allows you to call your event handler with arguments while still
passing the event to the handler.
function App() {
function handleClick(param) {
return (
Click Me
</button>
);
How It Works: The arrow function () => handleClick("Argument 1") creates a new
function that calls handleClick with the argument "Argument 1".
Using .bind()
The .bind() method can be used to pre-bind arguments to the event handler.
function App() {
function handleClick(param) {
return (
Click Me
</button>
);
How It Works: The .bind() method creates a new function with the specified param
value bound to the handleClick function.
Considerations: Like the arrow function, it creates a new function on each render.
function App() {
console.log("Param:", param);
return (
Click Me
</button>
);
36. What are the common event handlers in React, and how are they used?
React provides a wide range of event handlers to handle user interactions. These event
handlers are written in camelCase (e.g., onClick, onChange) and correspond to standard
DOM events. Here’s a breakdown of the most commonly used event handlers and their
usage:
74
Mouse Events
Keyboard Events
Form Events
75
Touch Events
Focus Events
React Router
React Router is a popular library in the React ecosystem used for handling navigation
and routing in a React application.
It enables you to build single-page applications (SPAs) with dynamic routing, allowing
users to navigate between different views or pages without reloading the browser.
a. Define the mapping between a URL path and the component to render.
76
import { BrowserRouter, Route, Routes } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<Routes>
</Routes>
</BrowserRouter>
);
Router Types:
Link Component:
function Navigation() {
return (
77
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
);
function Profile() {
// Routes definition
Programmatic Navigation:
function Login() {
function handleLogin() {
navigate("/dashboard");
App Structure
function App() {
return (
79
<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
</Routes>
</BrowserRouter>
);
function Home() {
function About() {
}
80
Dynamic routing in React allows you to create routes that can change based on
parameters, user input, or data. This is particularly useful for applications with dynamic
content, such as user profiles, blog posts, or product pages. React Router provides tools
to handle dynamic routing effectively.
function App() {
return (
<Router>
<Routes>
</Routes>
</Router>
81
);
In this example, :id is a route parameter that can be dynamically replaced by any value,
such as /user/123 or /user/john.
Use the useParams hook provided by React Router to extract parameters from the URL.
function UserProfile() {
function App() {
return (
<Router>
<Routes>
</Route>
</Routes>
</Router>
);
function UserProfile() {
const { id } = useParams();
return (
<div>
</div>
);
}
83
Query Parameters
function Search() {
function Dashboard() {
navigate(`/user/${userId}`);
84
};
return (
);
function App() {
return (
<Router>
<Routes>
</Routes>
85
</Router>
);
function UserProfile() {
const { id } = useParams();
if (!isValidId(id)) {
Forms in React
Controlled Components
In controlled components, the form inputs are controlled by React state. Each input
field's value is tied to a state variable.
function ControlledForm() {
name: "",
email: "",
message: "",
});
};
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Name:
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
/>
</label>
</div>
<div>
<label>
Email:
88
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
</label>
</div>
<div>
<label>
Message:
<textarea
name="message"
value={formData.message}
onChange={handleChange}
/>
</label>
</div>
<button type="submit">Submit</button>
</form>
);
89
}
Uncontrolled Components
In uncontrolled components, form inputs use the DOM's default behavior, and you
retrieve their values using ref.
function UncontrolledForm() {
e.preventDefault();
};
return (
90
<form onSubmit={handleSubmit}>
<div>
<label>
Name:
</label>
</div>
<div>
<label>
Email:
</label>
</div>
<button type="submit">Submit</button>
</form>
);
function FormWithValidation() {
setEmail(value);
if (!/\S+@\S+\.\S+/.test(value)) {
} else {
setError("");
};
e.preventDefault();
if (!error) {
};
return (
<form onSubmit={handleSubmit}>
92
<div>
<label>
Email:
</label>
</div>
Submit
</button>
</form>
);
For larger forms with many fields, consider using libraries like Formik, React Hook
Form, or Yup for validation.
Managing form validation in React involves ensuring that user inputs meet specific
requirements before processing or submitting data. React provides flexibility in
implementing validation, and you can choose between manual validation, custom logic,
or third-party libraries.
93
48. How do you integrate libraries like Formik or React Hook Form for form handling?
Integrating libraries like Formik or React Hook Form into your React application
simplifies form handling and validation. Here's a step-by-step guide for using each
library:
Formik Integration
Formik is a popular library for managing form state, validation, and submission in React
applications.
Basic Usage
Formik provides components like Formik, Form, Field, and ErrorMessage to handle
form operations.
function FormikExample() {
94
return (
<Formik
validate={(values) => {
if (!values.name) {
if (!values.email) {
} else if (!/\S+@\S+\.\S+/.test(values.email)) {
return errors;
}}
}}
>
<div>
<label>
Name:
</label>
</div>
<div>
<label>
Email:
</label>
</div>
Submit
</button>
</Form>
)}
96
</Formik>
);
email: Yup.string()
.required("Email is required"),
});
97
function FormikWithYup() {
return (
<Formik
validationSchema={validationSchema}
onSubmit={(values) => {
}}
>
<Form>
<div>
<label>
Name:
</label>
</div>
<div>
<label>
Email:
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
);
.required("Email is required"),
});
function ReactHookFormWithYup() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(validationSchema),
});
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
100
<label>
Name:
</label>
</div>
<div>
<label>
Email:
</label>
</div>
<button type="submit">Submit</button>
</form>
);
State Management
Prop drilling refers to the process of passing data from a parent component to deeply
nested child components in a React application through multiple intermediate
components.
It can become problematic as the application grows, making the code harder to
maintain, debug, and refactor.
If the Parent component has some data or functions needed by the GreatGrandchild,
you would need to pass these props down through every intermediate component (Child
and Grandchild), even if they don't use them directly.
function Parent() {
return <div>{data}</div>;
1. Cluttered Code: Components that don't use the props still have to handle and pass
them down.
2. Tight Coupling: Changes in the props structure require updates across multiple
components.
3. Reduced Reusability: Components become less reusable since they depend on
specific props being passed.
function Parent() {
return (
<DataContext.Provider value={data}>
<Child />
</DataContext.Provider>
);
function GreatGrandchild() {
return <div>{data}</div>;
Example:
function Parent() {
return render(data);
return <div>{data}</div>;
Example:
function GreatGrandchild() {
return <div>{data}</div>;
105
}
52. What are the common state management libraries used in React?
Here are some of the most common state management libraries used in React:
1. Redux
● Overview: Redux is one of the most popular state management libraries in React.
It follows a predictable state container approach using a unidirectional data flow.
● Key Features:
○ Centralized state management.
○ Strict unidirectional data flow.
○ Middleware support for asynchronous actions (e.g., redux-thunk,
redux-saga).
● When to Use:
○ Large-scale applications with complex state.
○ Need for debugging tools (Redux DevTools).
● Cons:
○ Boilerplate-heavy, though this has improved with the Redux Toolkit.
106
● Website: Redux
2. MobX
3. Zustand
4. Recoil
5. Jotai
7. XState
8. Apollo Client
When to Use:
Cons:
Both Redux and the React Context API are used for state management in React
applications, but they serve different purposes and have distinct characteristics. Here's a
detailed comparison:
1. Purpose
110
● Redux:
○ A React feature for sharing data across component trees without prop
drilling.
○ Best suited for lightweight state management, such as themes, user
authentication, or global configuration.
2. Learning Curve
● Redux:
3. Boilerplate
● Redux:
111
○ Historically known for being verbose, with separate files for actions,
reducers, and store configuration.
○ The Redux Toolkit significantly reduces boilerplate but still requires more
setup than Context API.
● Context API:
● Redux:
5. Performance
● Redux:
● Redux:
○ A rich ecosystem with tools like Redux DevTools for time-travel debugging
and state inspection.
○ Middleware and plugins for handling asynchronous operations, API calls, and
more.
● Context API:
7. Scalability
● Redux:
○ Built for scalability; ideal for applications with extensive state and multiple
developers.
○ Easily extendable and maintainable due to its clear structure.
● Context API:
○ Works well for smaller applications or isolated use cases (e.g., theming or
auth).
○ Can become unwieldy in large applications due to the lack of structure and
performance issues.
113
8. Asynchronous Logic
● Redux:
Summary
● Use Redux for large applications where state complexity, scalability, and
performance optimization are priorities.
● Use the Context API for simpler use cases, such as theming, authentication, or
small apps where Redux might feel like overkill.
In some scenarios, a combination of both might be appropriate: use Context API for
lightweight global state and Redux for managing complex application logic.
53. What are keys in React? Why are they important in lists?
1. Efficient Rendering: React uses keys to track which elements have changed in the
DOM. When the list changes (such as adding, removing, or reordering items), React can
efficiently update only the elements that have actually changed. Without keys, React
would have to re-render the entire list, which can be inefficient.
115
2. Preserving Component State: If the list elements are dynamic components (e.g.,
a list of input fields), keys help React maintain the internal state of each component,
even when the list is re-ordered or modified. Without keys, the state might get mixed up
because React could reuse components in the wrong order.
3. Identifying Changes in Dynamic Lists: When data changes, React uses the key
to match the updated data with the previously rendered elements, minimizing the
number of changes in the DOM.
54. Keys should be unique among siblings but don't have to be globally unique.
Commonly, you use an ID from your data as the key.
function List() {
return (
<ul>
))}
</ul>
);
In this example, item (the name of the fruit) is used as the key because it’s unique in this
list. If you have a more complex list, it’s common to use an ID from your data structure,
for example, key={item.id}.
116
Key Takeaways:
In React, you can implement conditional rendering using JavaScript operators like:
if (isLoggedIn) {
} else {
A more concise way to handle conditional rendering is by using the ternary operator:
return (
);
Here, if isLoggedIn is true, it renders "Welcome back!"; otherwise, it renders "Please log
in."
You can also use the && operator for rendering content conditionally, especially when
you want to render an element only when a certain condition is true.
return (
<div>
</div>
);
}
118
export default Message;
In this example, the paragraph with the message "You are logged in!" will only be
displayed if isLoggedIn is true.
Key Takeaways:
59. Conditional rendering is useful when you need to display content based on certain
conditions.
60. You can use if-else, ternary operators, or logical operators for conditional
rendering.
61. It's a common pattern for things like showing login forms, displaying different
views, or handling user permissions.
React.memo is used to wrap a component and makes React compare the current props
with the previous props. If the props haven't changed, the component is not
re-rendered, and React reuses the previous rendered output.
● The component receives the same props and doesn’t need to re-render.
● You want to prevent re-rendering of a child component when its parent re-renders.
Syntax:
return <div>{props.name}</div>;
119
});
In this example, MyComponent will only re-render if its props.name value changes. If the
name prop remains the same, React will skip rendering the component and use the
cached result.
Example:
});
function App() {
return (
<div>
</div>
);
In this example:
By default, React.memo performs a shallow comparison of the props. However, you can
provide a custom comparison function if you need more control over how props are
compared.
},
);
In this case, Greeting will only re-render if the name prop changes, regardless of
changes to age.
Key Takeaways:
Lazy loading in React is a technique that allows you to load components only when they
are needed, instead of loading them all at once at the initial render.
This can significantly improve the performance of your application, particularly for
larger applications with many components.
In React, lazy loading is achieved using the React.lazy() function, which allows you to
define components that will only be loaded when they're rendered.
122
React.lazy() allows you to dynamically import a component using code splitting.
When you use React.lazy(), React will automatically load the component only when
it's needed (i.e., when it’s rendered for the first time).
This helps in reducing the initial bundle size, leading to faster page loads.
Syntax:
Using Suspense:
Suspense is a built-in React component that lets you define what should be displayed
while the lazy-loaded component is being fetched. It’s like a loading state for
dynamically imported components.
// MyComponent.js
function MyComponent() {
}
123
export default MyComponent;
// App.js
function App() {
return (
<div>
<h1>Main App</h1>
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
</div>
);
}
124
export default App;
Lazy loading improves the performance of large React applications by splitting the
code and loading only the necessary components when needed.
Suspense is used to show a loading state while the component is being loaded.
Lazy loading is particularly useful for routes or components that are not immediately
required, allowing for faster initial rendering of the application.
Debugging
58. What are some common errors in React applications and how do you debug them?
59. How do you use React Developer Tools in a browser?
60. What is the purpose of error boundaries in React?
61. How do you handle errors in asynchronous operations in React?
React Ecosystem
In React, fragments are a lightweight way to group a list of child elements without
adding extra nodes to the DOM.
They were introduced to address scenarios where multiple child elements need to be
returned from a component but wrapping them in an unnecessary <div> or another
container would create unwanted DOM elements.
125
A fragment is represented using the <React.Fragment> component or its shorthand
syntax (<> </>). It does not produce any additional DOM nodes.
Example:
function Example() {
return (
<React.Fragment>
<h1>Heading</h1>
<p>This is a paragraph.</p>
</React.Fragment>
);
// Shorthand syntax
function ExampleShort() {
return (
<>
<h1>Heading</h1>
<p>This is a paragraph.</p>
</>
);
In both cases, the rendered output in the DOM will only contain the <h1> and <p>
elements without an additional wrapper.
126
Why Use Fragments?
function WithoutFragments() {
return (
<div>
<h1>Heading</h1>
<p>Text</p>
</div>
);
○ The extra <div> may interfere with CSS or lead to a less semantic structure.
2. Performance Optimization
○ Fragments avoid the cost of creating, managing, and rendering additional
DOM nodes.
○ They are especially useful in large or deeply nested component trees.
3. Simplify Code Structure
○ Using fragments helps keep the code clean and focused, especially when
rendering lists or conditional JSX elements.
4. Return Multiple Children from Components
○ React components must return a single parent element. Fragments allow
grouping multiple child elements without adding an unnecessary wrapper.
127
When to Use Fragments
Rendering Lists: When rendering multiple list items without needing a wrapper element
function List() {
return (
<>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</>
);
Layout Elements: Grouping child elements in a layout without disturbing the structure.
function Layout() {
return (
<>
<header>Header</header>
<main>Content</main>
<footer>Footer</footer>
</>
);
128
}
When Parent Element is Not Desired: To avoid DOM pollution in scenarios like table
rows, where extra nodes can break the structure.
function Table() {
return (
<table>
<tbody>
<>
<tr>
</tr>
<tr>
</tr>
</>
</tbody>
</table>
);
}
129
Limitations of Fragments
<React.Fragment key="uniqueKey">
<ChildComponent />
</React.Fragment>
1. Not Always Needed: In simpler scenarios, adding a parent element like <div> is
sufficient and doesn't harm performance significantly.
Key Takeaways
Fragments are a clean, efficient way to return multiple children without extra DOM
elements.
Use them to simplify your JSX structure and avoid unnecessary wrappers,
improving performance and reducing DOM clutter.
They are especially useful when working with lists, layouts, and components that
render multiple elements.
API Integration
useEffect(() => {
try {
if (!response.ok) {
setData(result);
} catch (error) {
131
setError(error.message);
} finally {
setLoading(false);
};
fetchData();
}, []); // Empty dependency array ensures this runs only once after the
component mounts.
return (
<div>
<h1>Posts</h1>
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
132
);
};
67. How do you handle loading and error states in API calls?
Handling loading and error states effectively in API calls ensures a smooth user
experience and makes your application more robust. Here's a detailed explanation with
an example:
1. Define States:
Example:
Example:
useEffect(() => {
setLoading(true);
setError(null);
try {
if (!response.ok) {
setData(result);
} catch (err) {
setError(err.message);
} finally {
};
134
fetchData();
}, []);
Handling pagination with APIs in React involves fetching a specific subset of data (e.g.,
a page) from the API and allowing users to navigate through the pages. Here's how you
can implement pagination step by step:
useEffect(() => {
setLoading(true);
setError(null);
try {
`https://jsonplaceholder.typicode.com/posts?_page=${currentPage}&_limit=
${itemsPerPage}`
);
if (!response.ok) {
setTotalPages(Math.ceil(totalItems / itemsPerPage));
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
};
fetchData();
};
if (currentPage > 1) {
};
return (
<div>
<h1>Paginated Posts</h1>
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
138
))}
</ul>
<div>
Previous
</button>
<span>
</span>
Next
</button>
</div>
</div>
);
};
Explanation:
139
69. Pagination State:
a. currentPage: Tracks the active page.
b. totalPages: Total number of pages (calculated from the X-Total-Count header).
70. API Call:
a. Fetches data for the current page using the _page and _limit query parameters.
71. Pagination Controls:
a. "Previous" and "Next" buttons to navigate between pages.
b. disabled property to disable buttons on boundary conditions.
72. Dynamic Dependency:
a. The useEffect hook re-fetches data whenever currentPage changes.
Both Axios and the Fetch API are popular tools for making HTTP requests in JavaScript.
While they can accomplish the same tasks, they differ in functionality, usability, and
features. Here’s a detailed comparison:
140
Testing React hooks ensures that they behave as expected under different conditions.
Here's how you can effectively test hooks:
Hooks like useState or useEffect need to run inside a functional React component. You
can create a test component to render and interact with the hook.
function TestComponent() {
return (
<div>
<p>Count: {count}</p>
);
render(<TestComponent />);
fireEvent.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
2. Using @testing-library/react-hooks
Installation
// Custom hook
function useCounter() {
// Initial state
expect(result.current.count).toBe(0);
// Increment counter
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
143
});
If your hook involves API calls, use mocking libraries like jest.fn() or msw.
// Mock axios
jest.mock('axios');
// Custom hook
function useFetchData(url) {
React.useEffect(() => {
144
axios.get(url).then((response) => setData(response.data));
}, [url]);
return data;
useFetchData('https://api.example.com/data')
);
await waitForNextUpdate();
expect(result.current).toEqual(mockData);
});
145
Hooks like useEffect or useLayoutEffect that interact with browser APIs (e.g.,
localStorage or window) require mocking those APIs.
});
React.useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
// Mock localStorage
mockGetItem.mockReturnValue(JSON.stringify(initialValue));
146
const { result } = renderHook(() => useLocalStorage(key,
initialValue));
expect(result.current[0]).toBe(initialValue);
act(() => {
result.current[1]('newValue');
});
expect(mockSetItem).toHaveBeenCalledWith(key,
JSON.stringify('newValue'));
});
When testing hooks with asynchronous operations like React Query or API fetching, use
@testing-library/react-hooks or libraries like msw to mock the server behavior.
// Mock axios
147
jest.mock('axios');
// Custom hook
function useFetchUser() {
return data;
});
<QueryClientProvider
client={queryClient}>{children}</QueryClientProvider>
);
148
const { result, waitFor } = renderHook(() => useFetchUser(), { wrapper
});
expect(result.current.data).toEqual(mockData);
});
Key Takeaways
79. What is the React Testing Library, and how does it differ from Enzyme?
77. Use .env files to configure different environments (e.g., development, production).
78. Define REACT_APP_ prefixed variables for use in the app.
Example .env.production:
REACT_APP_API_URL=https://api.example.com
REACT_APP_FEATURE_FLAG=true
b. Optimize Code
Before deploying, test the production build to ensure everything works as expected.
a. Code Splitting
● Ensure React splits your app into smaller chunks for faster loading.
● Enabled by default in create-react-app.
b. Lazy Loading
<LazyComponent />
</Suspense>
c. Caching
● Use cache control headers to cache static files for faster subsequent loads.
● Configure caching in your hosting platform or CDN.
d. Tree Shaking
● Remove unused exports from JavaScript files during the build process.
● Tools like Webpack automatically perform this for you in production builds.
a. Error Tracking
b. Performance Monitoring
c. Regular Updates
Example Workflow:
By following these steps, you'll have a React application that's optimized, secure, and
ready for a smooth user experience in production.
Yes, you can change the output folder name for the build directory in a React project.
However, the approach depends on the tools or configurations you use in your React
project. Below are some ways to customize the output folder:
By default, CRA uses build as the output folder. To change it, you’ll need to eject the
configuration or use a custom script or package.
Install react-app-rewired:
1.
2. Create a config-overrides.js file in the root of your project.
153
Add the following code to specify the output directory:
module.exports = {
return config;
},
};
3.
"scripts": {
}
154
4.
5. The output will now be in the folder you specified (e.g., custom-folder-name).
Locate the output property in the production configuration section and change the
path:
module.exports = {
// Other configurations...
155
output: {
filename: 'static/js/[name].[contenthash:8].js',
// other configurations...
},
};
3.
4.
For Vite
If you are using Vite instead of CRA, you can change the build folder in
vite.config.js:
build: {
},
});
2.
3.
If you're unable or unwilling to modify configurations, you can simply move the build
folder after building:
mv build custom-folder-name
While this doesn't change the default output location, it achieves the same result
manually.
157
Best Practices
● Avoid Ejecting: Ejecting makes your project harder to maintain. Use tools like
react-app-rewired or custom scripts where possible.
● Automation: If you move the build folder manually, consider writing a post-build
script in package.json to automate it.
Example:
"scripts": {
What is Webpack?
1. Module Bundling: Combines multiple files into one or more bundles for efficient
loading.
2. Loaders: Transforms files (e.g., transpile ES6+ to ES5 using Babel, process
CSS/SCSS, or load images).
3. Plugins: Enhance functionality (e.g., minification, environment-specific builds).
4. Code Splitting: Splits the app into smaller bundles for faster loading.
5. Tree Shaking: Removes unused code to optimize the final bundle.
6. Hot Module Replacement (HMR): Updates modules in the browser without a full
reload during development.
React applications consist of many modular components written in JavaScript, CSS, and
other assets. Webpack bundles these files into a single file (or multiple chunks) for the
browser, ensuring efficient delivery.
React typically uses modern JavaScript (ES6+) and JSX, which browsers don’t natively
understand. Webpack works with Babel, a transpiler, to convert this code into
browser-compatible JavaScript.
module.exports = {
module: {
rules: [
use: {
loader: 'babel-loader',
options: {
},
},
},
],
},
};
Webpack allows you to import and manage assets like CSS, images, and fonts directly in
your JavaScript files. This simplifies dependency management in React projects.
Example:
4. Development Server
Webpack's development server (Webpack Dev Server) provides features like live
reloading and Hot Module Replacement (HMR), making React development faster and
more convenient.
If you're using Create React App (CRA), Webpack is already configured for you:
You don't need to directly configure Webpack in CRA unless you eject the configuration:
⚠️ Warning: Ejecting makes the Webpack configuration accessible for manual changes
but harder to manage.
If you're not using CRA and want to set up Webpack manually for a React project:
161
Install Dependencies
Basic webpack.config.js
module.exports = {
output: {
},
module: {
rules: [
exclude: /node_modules/,
use: 'babel-loader',
162
},
},
use: 'file-loader',
},
],
},
plugins: [
new HtmlWebpackPlugin({
}),
],
devServer: {
static: './dist',
},
};
163
"scripts": {
"build": "webpack"
Folder Structure
my-react-app/
├── src/
├── public/
├── package.json
├── webpack.config.js
164
Conclusion
Webpack is a crucial tool in React development for bundling, transpiling, optimizing, and
managing dependencies. While tools like Create React App abstract away most of the
complexity, understanding Webpack is valuable for customizing builds, improving
performance, and managing complex projects.
What is Babel?
Babel is a popular JavaScript transpiler that converts modern JavaScript (ES6+), JSX,
and TypeScript code into a version of JavaScript that can run in older browsers. It
enables developers to write cutting-edge JavaScript features and syntaxes without
worrying about browser compatibility.
React applications often use modern JavaScript features and JSX syntax, neither of
which are natively supported by all browsers. Babel ensures that React applications work
seamlessly across different environments by:
1. Transpiling JSX
React uses JSX, a syntax extension that looks similar to HTML but is written inside
JavaScript. Browsers cannot interpret JSX directly, so Babel converts it into standard
JavaScript.
Transpiled Code:
React applications often use modern JavaScript features like let, const, arrow
functions, and async/await. Babel converts these features into a form compatible with
older JavaScript engines.
Transpiled Code:
console.log('Hello, World!');
};
166
3. Supporting Newer Proposals
Babel supports experimental JavaScript features via plugins, allowing developers to use
features that are not yet finalized.
1. Plugins
2. Presets
Presets are collections of plugins and configurations tailored for specific environments.
Popular presets include:
3. Polyfills
167
Babel can include polyfills for features not natively supported by certain browsers (e.g.,
Promise, Map, Set).
Babel is typically preconfigured in tools like Create React App (CRA). However, if you're
setting up Babel manually, here’s how:
1. Install Babel
module.exports = {
module: {
168
rules: [
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
],
},
};
You don’t need to set up Babel manually unless you eject the CRA configuration.
Summary
Babel is a critical tool in React development that ensures modern JavaScript and JSX
code can run on older browsers. It’s seamlessly integrated into most React build tools
like Create React App but can also be customized for advanced use cases.
These questions require a mix of creativity, deep technical understanding, and practical
experience. They help assess a developer's ability to tackle real-world challenges and
design scalable, performant React applications.
170
Here is a list of unique, scenario-based React.js questions aimed at assessing the deep
skills of an experienced React developer. These questions focus on complex scenarios,
optimization strategies, advanced patterns, and real-world applications.
Scenario: You have a React app that has multiple components re-rendering frequently,
especially when the state of a parent component changes. This impacts the
performance. How would you optimize the performance of this app?
Scenario: You are building a React app that displays large lists of data (e.g., 10,000+
items). Loading all the items at once is causing performance issues. How would you
handle this?
● Context API: Good for simpler applications with limited state requirements and
fewer updates. Best for small to medium-sized apps.
● Redux: More powerful for larger apps with complex state, action handling,
middleware (e.g., Redux Thunk), and debugging capabilities.
● Discuss how React Context can cause performance issues with deep component
trees due to unnecessary re-renders, while Redux can be more performant with
useSelector and memoization techniques.
Scenario: You notice that your React app is growing large in terms of bundle size. How
would you reduce the size of the React app's final bundle to improve loading times?
● Code splitting with React’s React.lazy() and Suspense for dynamic imports.
● Tree shaking to remove unused code when building the app (enabled by default in
Webpack).
● Using lighter libraries and avoiding large dependencies.
● Implementing asset compression (e.g., with tools like Webpack’s TerserPlugin or
using gzip/Brotli).
● Lazy loading images, videos, and other assets.
● Using CDN for serving third-party libraries.
● Analyzing bundle size with webpack-bundle-analyzer.
Answer: Use the useEffect hook with an empty dependency array ([]) to fetch data only
once when the component mounts:
useEffect(() => {
fetchData();
}, []);
● Discuss how useEffect works for handling side effects and how to avoid
unnecessary fetch calls by properly managing the dependency array.
Scenario: You need to build a custom hook that handles the logic for form validation,
including error state and form submission handling. How would you structure this custom
hook?
Scenario: You need to implement lazy loading for routes in your React app to improve
the performance of the initial load. How would you implement it?
Answer: Use React.lazy() to dynamically import components and wrap them with
Suspense:
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}
174
● Discuss how to use React.lazy() for route-based code splitting and the
performance benefits.
● Mention how Suspense provides a fallback UI during lazy loading.
Scenario: You're building a complex form with nested fields and dynamic inputs. How
would you manage the form state and validation?
● Using a controlled form with useState or useReducer for managing complex state.
● Implementing a form library like Formik or React Hook Form for easier state
management and validation.
● UseReducer could be helpful when the state has multiple values and nested
structures.
● Example of using useReducer:
Scenario: Your app has several dynamic components, and you want to ensure that if a
JavaScript error occurs in one component, it doesn't crash the entire app. How would
you implement this?
175
Answer: Discuss Error Boundaries:
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error, info) {
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
Scenario: You have a search input that triggers API calls on each keystroke. However,
you want to reduce the number of API calls and only trigger the API when the user stops
typing for a specified period. How would you implement this?
176
Answer: Use a debounce technique:
● Use the useEffect and useState hooks to trigger the search API call after the user
stops typing.
● Use a library like lodash.debounce for optimized debouncing. Example:
useEffect(() => {
if (query) {
debouncedSearch(query);
}
}, [query]);
Scenario: You’re building an app where users can toggle between light and dark themes.
You need to implement dynamic theme switching using React’s Context API.
Answer:
● Create a ThemeContext to store the current theme and a function to toggle it.
● Use useContext in components to access and update the theme.
177
● Example:
function App() {
const [theme, setTheme] = useState('light');
const toggleTheme = () => setTheme((prev) => (prev === 'light' ?
'dark' : 'light'));
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
<Navbar />
<Content />
</ThemeContext.Provider>
);
}
function Navbar() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<div>
<h1>{theme === 'light' ? 'Light Mode' : 'Dark Mode'}</h1>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
}
Scenario: Your app requires user authentication, and you need to persist user login state
even after the page reloads. How would you implement this in React?
178
Answer: Discuss how to handle authentication:
API requests.
● Use React Context or Redux to store the authenticated user state globally and
rehydrate the state on page reload.
● Implement a custom hook for authentication logic like login, logout, and token
management.
These questions focus on real-world challenges that require deep understanding and
problem-solving skills in React.js. They test the candidate’s ability to architect solutions
for performance, scalability, and maintainability in complex React applications.
Miscellaneous Questions
81. What are portals in React, and when would you use them?
82. What is the difference between server-side rendering (SSR) and client-side
rendering (CSR)?
83. What are the main features of React 18?
84. What are Suspense and Concurrent Mode in React?
85. How do you handle animations in React applications?
86. What is the difference between imperative and declarative programming in React?
This list covers a wide range of basic-level topics that are essential for understanding
ReactJS. It is ideal for evaluating beginners or developers with limited experience in
React.
179
Here’s a list of 100 practical ReactJS questions that could be asked of an experienced
developer. These questions cover concepts, coding skills, and debugging scenarios to
evaluate hands-on expertise.
React Basics
11. What is the Context API, and how do you use it?
12. How does React’s useEffect hook work? What are its dependencies?
13. What is the difference between useMemo and useCallback hooks?
14. How do you optimize a React application for performance?
15. What is React.memo? How does it help in performance optimization?
16. What is the difference between controlled and uncontrolled components?
17. How do you handle errors in React?
18. Explain the significance of keys in lists.
19. What are higher-order components (HOCs)?
20. What is React’s reconciliation process?
State Management
Routing
Performance Optimization
Testing
Debugging
This comprehensive list targets practical skills, problem-solving abilities, and real-world
scenarios.
183
Here is a curated list of unique, practical ReactJS questions to assess and deeply
probe an experienced developer’s skills. These questions are designed to challenge
problem-solving, debugging, and advanced understanding of React.
1. How would you design a React component library that supports theming and
custom styles?
2. Explain how you would optimize a component rendering a large data table with
frequent updates.
3. How would you implement a reusable and performant debounced search bar
component?
4. How do you structure a React project to handle multiple large-scale features
efficiently?
5. How would you implement dynamic rendering of different components based on
user permissions?
11. Design a context-based global state system without Redux for handling theme
and language settings.
12. How would you avoid unnecessary re-renders in deeply nested components using
Context API?
13. Implement a pub-sub mechanism using React’s Context and hooks.
14. How do you migrate a class-based Redux setup to a hooks-based Redux Toolkit
solution?
15. What is the best approach for integrating localStorage with state management in
React?
16. How would you create a reusable, dynamic form component that handles
validation for various field types?
17. How do you optimize forms with hundreds of input fields in React?
18. How would you implement a multi-step form with conditional rendering between
steps?
19. Explain how to handle asynchronous validation (e.g., checking username
availability) in forms.
20. How would you integrate React Hook Form with third-party UI libraries like
Material-UI or Ant Design?
21. How would you debug and fix a slow-rendering React application?
22. Explain how you would implement a memoized pagination component.
185
23. Describe a situation where React.memo might cause performance issues and how
you’d address it.
24. How would you measure and optimize the performance of a React app in
production?
25. How would you implement infinite scrolling without affecting app performance?
26. How do you design a React app to handle global errors and gracefully recover
from them?
27. How would you implement retry logic for failed API requests in React?
28. What is the purpose of error boundaries, and how do you extend them for logging
errors to an external service?
29. How do you debug and fix “setState on an unmounted component” warnings?
30. How would you handle React app failures in environments with unreliable internet?
Routing Challenges
31. How would you implement a custom breadcrumb navigation system with React
Router?
32. How do you optimize React Router for applications with deeply nested and
dynamic routes?
33. How would you implement route-based animations in a React application?
34. Explain how to handle conditional redirects based on user roles in React Router.
35. How do you preload data for a route in a React app before navigating to it?
36. How would you integrate server-side rendering (SSR) with React using Next.js or
similar frameworks?
186
37. How would you implement a shared session between a React app and another
non-React app?
38. Explain how to securely use third-party libraries in a React app without affecting
performance.
39. How would you handle external authentication systems (e.g., OAuth) in a React
SPA?
40. How do you integrate WebSockets for real-time updates in a React application?
Debugging Scenarios
41. Debug and resolve a situation where useEffect runs twice in development but not
in production.
42. How do you identify memory leaks in React apps and fix them?
43. How would you resolve a problem where a child component is causing a parent
component to re-render unnecessarily?
44. How do you debug why a component is rendering multiple times during an
interaction?
45. How do you troubleshoot a React app that occasionally freezes or crashes?
46. How do you implement the Compound Component pattern in React? Provide an
example.
47. What is the Provider pattern, and when would you use it over HOCs?
48. How would you design a plugin system for a React application to allow
extensibility?
49. Explain the differences and trade-offs between the Container-Presenter and
Render Props patterns.
50. How would you handle feature flags in a React application to toggle features
dynamically?
187
Real-World Problem-Solving
51. How would you migrate a legacy React app to a modern architecture without
downtime?
52. How do you design a React app that supports offline mode with automatic
syncing?
53. Explain how you would implement dynamic component loading based on user
preferences or behavior.
54. How do you manage long-running background tasks in a React app?
55. How do you ensure accessibility compliance (e.g., WCAG standards) in a React
project?
Testing
56. How would you test a component with complex hooks and asynchronous effects?
57. How do you mock a Redux store for testing connected components?
58. Explain how you test error boundaries in React.
59. How would you write an end-to-end test for a React app with dynamic routing?
60. How do you test React components that rely on external APIs?
Custom Implementations