React JS Ebook Interview Questions
React JS Ebook Interview Questions
But remember:
1. Variety of Questions: The same questions can be asked in many different ways, so don't just
memorise the answers. Try to understand the concept behind each one.
2. Expect Surprises: There might be questions during your interview that are not on this list. It's
always good to be prepared for a few surprises.
3. Use This as a Starting Point: Think of this material as a starting point. It shows the kind of
questions you might encounter, but it's always good to study beyond this list during your course.
Examples:
function App() {
return (
<div>
<h1>Hello, React!</h1>
</div>
);
}
Reusing Components:
jsx
import React from 'react';
function Greeting(props) {
return <p>Hello, {props.name}!</p>;
}
Features:
Virtual DOM: React introduces a Virtual DOM, a lightweight representation of the actual DOM
in memory. This allows React to efficiently update the real DOM by only making necessary
changes, improving performance.
Declarative Syntax: React uses a declarative syntax, where you describe the desired UI state,
and React handles updating the DOM to match that state. This makes the code more intuitive
and easier to understand.
Unidirectional Data Flow: React enforces a unidirectional data flow, which means data flows
in a single direction from parent to child components. This helps maintain a clear and
predictable data flow in the application.
JSX (JavaScript XML): JSX is a syntax extension that allows you to write HTML-like code
within your JavaScript. It makes the creation of React elements more intuitive and readable.
Reusable Components: React encourages the creation of reusable components, which can
be used across different parts of the application, leading to a more modular and maintainable
codebase.
State Management: React components can manage their own state, making it easier to
handle dynamic data and user interactions. The introduction of hooks (e.g., `useState`,
`useEffect`) has further improved state management.
Rich Ecosystem: React has a vast ecosystem of third-party libraries, tools, and extensions
that enhance its functionality. This includes state management libraries like Redux, routing
solutions like React Router, and many more.
React's combination of these features makes it a powerful tool for building modern, interactive,
and efficient user interfaces for web applications.
React components are the building blocks of a user interface in a React application. They are
reusable, self-contained units of code that encapsulate specific functionality and can be
composed together to create complex UIs. In React, everything is a component, from a small
button to an entire page.
Components can be thought of as custom HTML elements with JavaScript logic attached to
them. They can represent different parts of a user interface, such as buttons, forms, navigation
menus, cards, modals, and more. React components are designed to promote reusability,
modularity, and maintainability in your application.
function Button(props) {
return <button onClick={props.onClick}>{props.label}</button>;
}
Class Components: These are defined as JavaScript classes that extend the
`React.Component` class. They have a more extensive feature set, including the ability to
manage state, use lifecycle methods, and access component-specific methods.
increment = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
Components can also be divided into smaller components, forming a hierarchical structure
known as the component tree. The top-level component is usually the main application
component, while the lower-level components represent the different UI elements and
functionalities. React components enable you to create a dynamic and interactive user interface
by combining and composing these building blocks.
3. What is JSX?
JSX (JavaScript XML) is an extension to JavaScript that allows you to write HTML-like syntax
directly in your JavaScript code. It is commonly used in React to define the structure of UI
components.
Example:
jsx
const element = <h1>Hello, JSX!</h1>;
10. What is the "key" prop and what is the benefit of using it in arrays of elements?
The "key" prop is used to help React identify which items have changed, been added, or been
removed in a list of elements. It improves performance by allowing React to update only the
necessary parts of the DOM.
Example:
jsx
const list = todos.map(todo => <lo key={todo.id}>{todo.text}</li>);
Example:
jsx
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = { value: '' };
}
render() {
return (
<input type="text" value={this.state.value} onChange={this.handleChange} />
Example:
jsx
class UncontrolledInput extends React.Component {
render() {
return (
<input type="text" ref={input => this.input = input} />
);
}
}
Example:
jsx
const withLogger = WrappedComponent => {
return class extends React.Component {
componentDidMount() {
console.log('Component is mounted');
}
render() {
return <WrappedComponent {...this.props} />;
}
};
};
17. Why does React use `className` over the `class` attribute?
React uses `className` instead of `class` to set CSS classes on elements. This is because
`class` is a reserved keyword in JavaScript, and JSX is a JavaScript extension.
Example:
jsx
class App extends React.Component {
render() {
return (
<>
<Header />
<MainContent />
<Footer />
</>
);
}
}
Example:
jsx
function useFetchData(url) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => setData(data));
}, [url]);
return data;
}
26. Differentiate Between SSR (Server-Side Rendering) and CSR (Client-Side Rendering).
SSR renders the initial HTML on the server and sends it to the client, improving SEO and initial
load time. CSR renders the page using JavaScript on the client side, allowing for dynamic
updates and a smoother user experience.
The core idea behind Redux is to provide a single source of truth for the state of an application.
Instead of having scattered and potentially conflicting states across different components,
Redux centralizes the state management into a "store." Components can then interact with the
store to read or update the application state.
Store: The central repository of the application state. It holds the entire state tree of the
application. The state can only be modified by emitting an action.
Actions: Actions are plain JavaScript objects that describe what happened in the application.
They carry information (payload) about the type of action being performed and any additional
data required to update the state.
Reducers: Reducers are functions that specify how the application's state changes in
response to actions. They take the current state and an action as input and return a new state.
Reducers should be pure functions that do not modify the state directly.
Dispatch: A function provided by Redux that allows components to send actions to the store.
When an action is dispatched, it triggers the state update process.
Selectors: Functions that are used to extract specific pieces of data from the state in a
structured way. Selectors help in efficiently accessing and computing derived data from the
state.
Middleware: Middleware functions can be used to intercept actions before they reach the
reducers. Middleware is often used for tasks like logging, making asynchronous API calls, or
modifying actions before they reach the reducers.
Redux provides a clear separation of concerns and helps manage complex application states,
making it easier to debug, test, and maintain large-scale applications. While Redux can add
some initial complexity to a project, it becomes highly beneficial as the application grows and
the state management requirements become more intricate. It's important to note that with the
introduction of React Hooks and context API improvements, the need for using Redux has
diminished in some cases, but it still remains a popular choice for state management in many
projects.
Performance:
● Redux: Redux is optimized for performance through its use of immutable data updates
and shallow comparisons. This can lead to efficient updates, especially when dealing
with deeply nested state structures.
● Context API: The Context API can be less performant in some scenarios, particularly
when updates occur frequently or deeply nested components trigger updates. However,
React has made optimizations to improve the performance of the Context API over time.
In summary, Redux is a more powerful and structured solution for complex state management
needs, while the Context API provides a simpler and more lightweight way to share state in
smaller applications or specific use cases. The choice between Redux and the Context API
depends on the specific requirements and complexity of your application.
Flux:
● Components: In Flux, components are responsible for triggering actions and receiving
updates from stores.
● Actions: Actions are plain JavaScript objects that describe an event that occurred. They
are created and dispatched by components to signal changes in the application.
● Dispatcher: The dispatcher is a central hub that receives all actions and dispatches
them to the appropriate stores. It ensures that actions are processed in a sequential
order.
● Stores: Stores contain the application state and the business logic for handling actions.
They update their state in response to actions and emit change events to notify
components of state changes.
● Unidirectional Data Flow: Flux enforces a unidirectional data flow, meaning that data
changes flow in a single direction: from components to actions, through the dispatcher to
stores, and then back to components for rendering.
Redux:
● Components: In Redux, components interact with the state using actions and receive
state updates through subscriptions.
● Reducers: Redux introduces the concept of reducers, which are pure functions
responsible for updating the application state based on actions. Reducers take the
current state and an action as inputs and return a new state.
● Store: Redux uses a single, centralized store that holds the entire application state. The
state is managed by reducers, and components can subscribe to the store to receive
updates.
● Middleware: Redux supports middleware, which are functions that can intercept and
process actions before they reach the reducers. Middleware is useful for tasks like
logging, making asynchronous requests, and more.
● DevTools: Redux has a powerful ecosystem of developer tools that make it easier to
debug, visualize state changes, and track action flows.
● Immutable State: Redux encourages the use of immutable state updates to track
changes efficiently and prevent accidental mutations.
In summary, both Flux and Redux aim to provide a structured approach to state management in
React applications, but Redux introduces some additional concepts and features like reducers,
a single store, middleware, and dev tools. Redux simplifies the Flux pattern and provides a
more standardized and predictable way to manage application state. It's worth noting that
Redux was created as a response to some of the challenges and complexities developers
encountered when implementing the Flux architecture in large-scale applications.
State Management: Stateful components have the ability to define and update their own state
using the `setState` method. The state represents data that can change over time and affects
how the component renders and behaves.
jsx
import React, { Component } from 'react';
incrementCount = () => {
this.setState(prevState => ({
count: prevState.count + 1
}));
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
In the example above, the `Counter` component is a stateful component that maintains its own
`count` state. When the "Increment" button is clicked, the `incrementCount` method is called,
which uses `setState` to update the state and trigger a re-render.
It's important to note that with the introduction of React Hooks, functional components can also
manage state using the `useState` hook, blurring the distinction between stateful class
components and functional components. Hooks provide a more concise and modern way to
manage state and lifecycle behavior within functional components.
Manage URL Navigation: A router enables navigation between different views or components
based on the URL. Each URL can correspond to a specific component or view within your
application. Users can use browser navigation or your application's navigation controls (like
links or buttons) to switch between different views.
Deep Linking: A router allows you to create deep links to specific sections of your application.
Users can bookmark or share these deep links, and when they access them, the router ensures
that the correct component or view is displayed.
Maintain a Clean UI Structure: With a router, you can organize your application into logical
sections or pages, making it easier to manage and maintain your codebase as it grows.
Improve User Experience: A router can provide a smoother and more intuitive user
experience by allowing users to navigate between different views without the need for a full
page reload. This can improve the perceived performance of your application.
Code Splitting: Routers often support code splitting, which means that different views or
components can be loaded asynchronously, improving the initial load time of your application by
only loading the code that is needed for the current view.
There are several router libraries available for React, such as React Router and Reach Router.
These libraries provide components and utilities to help you implement routing in your
application.
In summary, a router is required in React when you want to create multi-page applications,
handle different views or pages based on URLs, and provide a seamless and efficient user
experience when navigating between those views. It helps in organizing, managing, and
enhancing the overall user interface and navigation of your React application.
Store: The store is the centralized place where the entire application state is stored. It
represents the single source of truth for the data. The store is created using the `createStore`
function from the Redux library. The store holds the application's state and exposes methods to
dispatch actions and subscribe to state changes.
Reducers: Reducers are pure functions responsible for updating the state based on the
dispatched actions. Each reducer handles a specific portion of the application's state. Reducers
take the current state and an action as input, and they return a new state object that reflects the
changes. Redux uses the combined reducers approach to manage multiple reducers together.
Dispatch: Dispatching an action is the process of sending an action to the Redux store. This
triggers the state update process, where reducers process the action and produce a new state.
Dispatching actions is typically done by components when they need to update the application
state.
Selectors: Selectors are functions that allow you to extract specific pieces of data from the
state in a structured and efficient way. They help in abstracting the structure of the state and
provide a clean way to access data from the store.
Middleware: Middleware are functions that sit between dispatching an action and the moment
it reaches the reducer. Middleware can intercept, modify, or dispatch additional actions before
they reach the reducer. Middleware is often used for handling asynchronous operations,
logging, or other custom behaviors.
Provider Component: In a React application, the `Provider` component from the `react-redux`
library is used to wrap the root component. It provides the Redux store to all components in the
application, making it accessible through the React context API. This eliminates the need to
manually pass the store down the component tree.
Connect Function: The `connect` function from the `react-redux` library is used to connect
React components to the Redux store. It provides a way to access state and dispatch actions
from within a component. The `connect` function takes care of subscribing to the store and
updating the component when the state changes.
These components work together to implement the Flux-like architecture that Redux follows,
providing a predictable and efficient way to manage state in React applications.
Long answer
The `componentWillReceiveProps` lifecycle method was a part of the React class component
lifecycle prior to React version 16.3. With the introduction of React 16.3, this lifecycle method
has been deprecated, and its use is discouraged in favor of other lifecycle methods and
patterns. Instead of `componentWillReceiveProps`, you should use `componentDidUpdate`
along with the `componentDidMount` lifecycle methods to handle similar scenarios.
jsx
class MyComponent extends React.Component {
componentWillReceiveProps(nextProps) {
if (this.props.someProp !== nextProps.someProp) {
// Perform actions or updates based on prop changes
}
}
render() {
// Render component's UI
}
}
Derived State: In some cases, you can use the `getDerivedStateFromProps` static method to
compute derived state based on prop changes. This method is a safer alternative for managing
state based on props and is called before rendering.
Here's an example of how you might use the `componentDidUpdate` method to achieve similar
behavior:
jsx
class MyComponent extends React.Component {
componentDidUpdate(prevProps) {
if (this.props.someProp !== prevProps.someProp) {
// Perform actions or updates based on prop changes
}
}
render() {
// Render component's UI
}
}
Long Answer
When a component's state or props change, React will automatically trigger a re-render of the
component's UI to reflect those changes. However, in some cases, you might want to prevent
unnecessary re-renders to improve performance, especially if the component's UI doesn't need
to be updated based on certain changes in state or props.
Here's a basic example of how you might use the `shouldComponentUpdate` method to
optimize rendering:
```jsx
class MyComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// Compare current props and state with next props and state
if (this.props.someProp === nextProps.someProp && this.state.someState ===
nextState.someState) {
return false; // Prevent re-render if the specific conditions are met
}
return true; // Allow re-render if conditions are not met
}
It's worth noting that as of my knowledge cutoff in September 2021, React introduced the
`React.PureComponent` class and the `React.memo` higher-order component, both of which
provide automatic shallow prop and state comparison to determine if a re-render is necessary.
These mechanisms can often make manual usage of `shouldComponentUpdate` less
necessary.
Long Answer
The `useEffect` hook is a fundamental and versatile feature in React's functional components
that allows you to perform side effects in your components. Side effects are actions that are not
directly related to rendering UI, such as data fetching, subscriptions, manipulating the DOM,
In class components, side effects were typically managed using lifecycle methods like
`componentDidMount`, `componentDidUpdate`, and `componentWillUnmount`. With the
introduction of functional components and hooks, the `useEffect` hook provides a unified way to
handle all these scenarios in one place.
Here's a basic example of how you might use the `useEffect` hook to fetch data from an API
when a component mounts:
```jsx
import React, { useState, useEffect } from 'react';
function DataFetchingComponent() {
const [data, setData] = useState(null);
useEffect(() => {
// This function will run when the component mounts
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data))
.catch(error => console.error(error));
}, []); // Empty dependency array means this effect runs only once, like componentDidMount
return (
<div>
{data ? (
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
):(
<p>Loading...</p>
)}
</div>
);
}
```
Declarative Side Effects: The `useEffect` hook takes two arguments. The first argument is a
function that contains the code you want to run for the side effect. The second argument is an
array of dependencies. The effect will re-run whenever any value in the dependency array
changes.
No Blocking: The code inside `useEffect` runs asynchronously after the component has
rendered. This means that it won't block the rendering of the component.
Multiple Effects: You can use multiple `useEffect` hooks in a single component to separate
different side effects and their corresponding cleanup logic.
Conditional Effects: You can conditionally apply effects based on certain conditions within the
component.
The `useEffect` hook is a powerful tool that simplifies and streamlines managing side effects in
React functional components, making the code more organized and maintainable compared to
using multiple lifecycle methods in class components.
40. How can you prevent the default behavior of an event in React?
In React, you can prevent the default behavior of an event by calling the `preventDefault()`
method on the event object. For example, to prevent a form submission from triggering a page
reload.