![]() |
VOOZH | about |
ReactJS is an open-source JavaScript library used to build fast and interactive user interfaces with reusable components, focusing mainly on the view layer.
Before proceeding to learn ReactJS Interview Questions and Answers – Advance Level, you can first go through complete ReactJS Tutorial, ReactJS Interview Questions and Answers – Beginner Level.
Custom hooks are JavaScript functions that start with the prefix use and leverage React’s built-in hooks (e.g., useState, useEffect) to encapsulate reusable logic. They promote the DRY (Don’t Repeat Yourself) principle, allowing developers to extract complex logic from components and reuse it across the application. Custom hooks simplify code, improve maintainability, and enhance testability by isolating logic from UI.
Common Custom Hooks:
Example (useFetch):
import { useState, useEffect } from 'react';
// Example custom hook: useFetch
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
setLoading(true);
setError(null);
try {
const response = await fetch(url, {
signal: controller.signal,
});
if (!response.ok) {
throw new Error(`HTTP error! ${response.status}`);
}
const result = await response.json();
setData(result);
} catch (err) {
if (err.name !== 'AbortError') {
setError(err);
}
} finally {
setLoading(false);
}
};
fetchData();
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
Optimizing React code enhances application performance, reduces load times, and improves user experience. Advanced optimization techniques focus on minimizing re-renders, reducing bundle size, and improving rendering efficiency.
Optimization Techniques:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Clicked');
}
render() {
return <button onClick={this.handleClick}>Click</button>;
}
}return (
<>
<h1>Title</h1>
<p>Content</p>
</>
);React.lazy: Load components only when needed to reduce initial bundle size. const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}const MyComponent = React.memo(({ data }) => <div>{data}</div>);Points:
Both useRef and createRef create mutable references in React, but they differ in their usage, behavior, and context.
| useRef | createRef |
|---|---|
| Hook used in React | Function used in React |
| Used in functional components | Used in class components |
| Persists the same ref object across re-renders | Creates a new ref object on every render |
| Returns an object with a current property | Returns an object with a current property |
| Used for DOM references instance variables and storing previous values | Mainly used for DOM references in class components |
| Syntax: const ref = useRef(null) | Syntax: this.ref = React.createRef() |
Example (useRef):
import { useRef, useEffect } from 'react';
function InputFocus() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
}Example (createRef):
class InputFocus extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount() {
this.inputRef.current.focus();
}
render() {
return <input ref={this.inputRef} />;
}
}React Redux is the official React binding for Redux, a state management library that centralizes application state in a single store. It simplifies passing state between components, eliminating the need for prop drilling in large applications. Redux ensures predictable state updates through a unidirectional data flow, making it ideal for complex apps with shared state.
Example:
import { configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider, useSelector, useDispatch } from 'react-redux';
// Slice
const counterSlice = createSlice({
name: 'counter',
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1;
},
},
});
const { increment } = counterSlice.actions;
// Store
const store = configureStore({
reducer: counterSlice.reducer,
});
// Component
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<p>{count}</p>
<button onClick={() => dispatch(increment())}>Increment</button>
</div>
);
}
// App
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}React Redux offers several advantages for managing state in React applications, particularly in large or complex projects.
Benefits:
Points:
React Redux relies on four core concepts that define how data flows through a Redux-powered React application.
Core Components:
import { createStore } from 'redux';
const store = createStore(reducer);const increment = () => ({ type: 'INCREMENT' });type property (and optional payload) that trigger state changes. { type: 'INCREMENT', payload: 1 }const reducer = (state = { count: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
};In Redux, large applications often require multiple reducers to manage different parts of the state. The combineReducers function from Redux merges these reducers into a single root reducer, which is then passed to the store.
Syntax:
import { combineReducers } from 'redux';
const rootReducer = combineReducers({
reducer1: reducer1,
reducer2: reducer2,
});Example:
import { createStore, combineReducers } from 'redux';
// Books Reducer
const booksReducer = (state = [], action) => {
switch (action.type) {
case 'ADD_BOOK':
return [...state, action.payload];
default:
return state;
}
};
// Active Book Reducer
const activeBookReducer = (state = null, action) => {
switch (action.type) {
case 'SELECT_BOOK':
return action.payload;
default:
return state;
}
};
// Combine Reducers
const rootReducer = combineReducers({
books: booksReducer,
activeBook: activeBookReducer,
});
// Create Store
const store = createStore(rootReducer);The Context API is a React feature for sharing global state across a component tree without prop drilling. It’s lightweight, built into React, and ideal for managing data like themes, authentication, or locale settings. Context consists of a Provider to supply data and a Consumer (or useContext hook) to access it.
Syntax:
const MyContext = React.createContext(defaultValue);Example:
import { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
);
}
function Child() {
const theme = useContext(ThemeContext);
return <div>Theme: {theme}</div>;
}The Context API uses two key components to manage data flow: Provider and Consumer.
Example:
import { createContext, useContext } from 'react';
const UserContext = createContext(null);
function App() {
const user = { name: 'John' };
return (
<UserContext.Provider value={user}>
<Child />
</UserContext.Provider>
);
}
function Child() {
const user = useContext(UserContext);
return <div>User: {user.name}</div>;
}Cross-Origin Resource Sharing (CORS) is a security mechanism that allows or restricts requests from a different domain than the server’s. In React, CORS issues arise when the frontend (e.g., running on localhost:3000) makes requests to a backend on a different domain (e.g., api.example.com). Axios, a popular HTTP client, can be configured to handle CORS-compliant requests.
Handling CORS:
Example (Axios with CORS):
import axios from 'axios';
function fetchData() {
axios.get('https://api.example.com/data', {
headers: {
'Content-Type': 'application/json',
},
withCredentials: true, // If cookies or auth are needed
})
.then(response => console.log(response.data))
.catch(error => console.error('CORS error:', error));
}Axios is a promise-based HTTP client for making asynchronous requests to REST APIs. It’s widely used in React for CRUD operations due to its simplicity, support for the Promise API, and features like request cancellation and interceptors.
Installation:
npm install axiosExample:
import { useState, useEffect } from 'react';
import axios from 'axios';
function DataFetcher() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
axios.get('https://api.example.com/data')
.then(response => {
setData(response.data);
setLoading(false);
})
.catch(error => console.error('Error:', error));
}, []);
if (loading) return <div>Loading...</div>;
return <div>Data: {data.name}</div>;
}This program demonstrates a simple counter using the useState hook to manage state and event handlers for incrementing and decrementing the count. The UI updates automatically when the state changes.
Example:
import React, { useState } from 'react';
function Counter() {
const [counter, setCounter] = useState(0);
const handleIncrement = () => {
setCounter(counter + 1);
};
const handleDecrement = () => {
setCounter(counter - 1);
};
return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h2>React Counter</h2>
<div style={{ fontSize: '24px', margin: '20px' }}>{counter}</div>
<div>
<button
onClick={handleIncrement}
style={{ margin: '5px', padding: '10px 20px' }}
>
Increment
</button>
<button
onClick={handleDecrement}
style={{ margin: '5px', padding: '10px 20px' }}
>
Decrement
</button>
</div>
</div>
);
}
export default Counter;How It Works:
Points:
In React, state updates with setState (in class components) or useState setters are asynchronous to optimize performance. Using a callback-based approach ensures updates are based on the previous state, preventing bugs when multiple updates occur in quick succession.
Why Use Callbacks:
Example (Class Component):
class Counter extends React.Component {
state = { count: 0 };
handleClick = () => {
this.setState(prevState => ({
count: prevState.count + 1,
}));
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
}Example (Functional Component):
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(prevCount => prevCount + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment</button>
</div>
);
}Material UI is a popular React UI framework that provides pre-built components following Google’s Material Design guidelines. It offers customizable, accessible, and responsive components for building modern React applications. Material UI is widely used for its ease of integration and compatibility with frameworks like React, Angular, and Vue.
Example:
import { Button, TextField } from '@mui/material';
function Form() {
return (
<div>
<TextField label="Name" variant="outlined" />
<Button variant="contained" color="primary">
Submit
</Button>
</div>
);
}Flux is an application architecture popularized by Facebook for managing data flow in React applications. It emphasizes unidirectional data flow, which Redux builds upon. Flux consists of four parts: Dispatcher, Stores, Actions, and Views (React components).
Flux in Redux:
Points:
The useMemo hook memoizes expensive computations in functional components, returning a cached value unless its dependencies change. It optimizes performance by preventing redundant calculations during re-renders.
Syntax:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);Example:
import { useMemo, useState } from 'react';
function ExpensiveComponent({ numbers }) {
const [count, setCount] = useState(0);
const sum = useMemo(() => {
console.log('Calculating sum...');
return numbers.reduce((acc, num) => acc + num, 0);
}, [numbers]);
return (
<div>
<p>Sum: {sum}</p>
<button onClick={() => setCount(count + 1)}>Re-render ({count})</button>
</div>
);
}The useState hook’s setter function does not update state immediately. React batches state updates for performance and processes them asynchronously during the next render cycle. This queuing mechanism ensures React knows which state corresponds to which component, but it can lead to stale state if not handled properly.
Example:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
console.log(count); // Logs old value due to async update
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment</button>
</div>
);
}
Solution: Use a functional update to ensure updates are based on the latest state:
setCount(prevCount => prevCount + 1);These hooks serve distinct purposes in optimizing and managing functional components.
useEffect(() => {
fetchData();
return () => cleanup();
}, [dependency]);const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);When to Use:
Points:
React Router provides three types of routers for handling navigation in React applications, each suited for different use cases.
Types of Routers:
import { BrowserRouter } from 'react-router-dom';import { HashRouter } from 'react-router-dom';import { MemoryRouter } from 'react-router-dom';StrictMode is a React component that wraps parts of an application to highlight potential issues during development. It doesn’t render any UI but enables additional checks and warnings to improve code quality.
Features:
Example:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);Conditional rendering in React involves dynamically displaying components or elements based on conditions like state, props, or API responses. It’s essential for creating responsive UIs tailored to user interactions or data.
Use Cases:
Example:
import { useState } from 'react';
function UserStatus() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<div>
{isLoggedIn ? <h1>Welcome, User!</h1> : <h1>Please Log In</h1>}
<button onClick={() => setIsLoggedIn(!isLoggedIn)}>
{isLoggedIn ? 'Log Out' : 'Log In'}
</button>
</div>
);
} React Router is a library for managing navigation in React single-page applications (SPAs). It enables dynamic routing, allowing components to render based on the URL without full page reloads, providing a seamless user experience.
Example:
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
function Home() {
return <h2>Home Page</h2>;
}
function About() {
return <h2>About Page</h2>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link> | <Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Router>
);
}
export default App;How It Works:
Points:
Routes instead of Switch in React Router v6. React Hooks and class components offer different approaches to building React applications, with hooks being the modern standard.
Comparison Table:
| Feature | React Hooks | Class Components |
|---|---|---|
| State Management | useState for state | this.state and this.setState |
| Reusability | Custom hooks for shared logic | Inheritance or HOCs, more complex |
| this Keyword | No this; direct access to state/functions | Uses this for state and methods |
| Lifecycle Methods | useEffect for side effects | componentDidMount, componentDidUpdate, etc. |
| Performance | Better optimizations with hooks API | Less efficient, more boilerplate |
Example (Hooks):
import { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}Example (Class):
class Counter extends React.Component {
state = { count: 0 };
componentDidMount() {
document.title = `Count: ${this.state.count}`;
}
componentDidUpdate() {
document.title = `Count: ${this.state.count}`;
}
render() {
return (
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
{this.state.count}
</button>
);
}
}Data in React flows primarily through props, but other methods exist for complex scenarios.
Methods:
function Parent() {return <Child name="John" />;}function Child({ name }) {return <div>{name}</div>;}
function Parent() {
const [data, setData] = useState('');
return <Child setData={setData} />;
}
function Child({ setData }) {
return <button onClick={() => setData('Updated')}>Update</button>;
}Points:
Lazy loading defers loading components until they’re needed, reducing initial bundle size and improving app performance. React provides React.lazy and Suspense for implementing lazy loading.
Example:
import { lazy, Suspense } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}Redux is a state management library for predictable state updates. Its core components are:
Example:
import { configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider, useSelector, useDispatch } from 'react-redux';
// Slice
const counterSlice = createSlice({
name: 'counter',
initialState: { count: 0 },
reducers: {
add: (state, action) => {
state.count += action.payload;
},
},
});
const { add } = counterSlice.actions;
// Store
const store = configureStore({
reducer: counterSlice.reducer,
});
// Component
function Counter() {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch(add(1))}>
Add
</button>
</div>
);
}
// App
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}React Router handles client-side routing for SPAs, while conventional routing typically involves server-side routing for multi-page applications.
Comparison Table:
| Feature | React Routing | Conventional Routing |
|---|---|---|
| Page Loading | No full reload; components render dynamically | Full page reload on navigation |
| SEO | Requires SSR or prerendering for SEO | Naturally SEO-friendly due to server rendering |
| Navigation | JavaScript-driven with Link/NavLink | Server-driven with <a> tags |
| Technology | Client-side via React Router | Server-side (e.g., Express, PHP) |
| URL Structure | Supports dynamic parameters (e.g., /user/:id) | Typically static URLs |
In class components, event handlers require binding to ensure the correct this context. However, binding can be avoided to reduce boilerplate and improve performance.
Methods to Avoid Binding:
this. class MyComponent extends React.Component {
handleClick = () => {
console.log(this.state);
};
render() {
return <button onClick={this.handleClick}>Click</button>;
}
}<button onClick={() => this.handleClick()}>Click</button>function MyComponent() {
const handleClick = () => {
console.log('Clicked');
};
return <button onClick={handleClick}>Click</button>;
}Props (properties) are read-only data passed from a parent component to a child component to configure its behavior or appearance. They enable component reusability and dynamic rendering.
Example:
function Parent() {
return <Child name="Alice" age={25} />;
}
function Child({ name, age }) {
return <div>{name} is {age} years old</div>;
}CSS Modules scope styles locally to a component, preventing style conflicts in large applications. They generate unique class names at build time, ensuring styles apply only to the intended component.
Example:
/* styles.module.css */
.button {
background-color: blue;
color: white;
}import styles from './styles.module.css';
function Button() {
return <button className={styles.button}>Click</button>;
}