Land the job you want — prepare
with Real interviews Q&A
Curated interview questions, company-wise guides and coding rounds. Practice mock interviews, improve with feedback, and track your progress.
React is a popular JavaScript library used for building user interfaces (UI), especially for web applications. It was created by Meta (formerly Facebook) and is widely used to build fast, interactive websites.
React lets you build a webpage as a collection of reusable components — small pieces of UI like buttons, forms, or menus — that can manage their own data and update efficiently.
Key ideas in React- Components: Building blocks of the UI (navbar, card, button, etc.)
- JSX: A syntax that looks like HTML but lives inside JavaScript.
- State: Data that changes over time (counter, user input).
- Props: Data passed from one component to another.
- Virtual DOM: A lightweight copy of the real DOM for fast updates.
- Fast updates via the Virtual DOM
- Reusable components
- Strong ecosystem and community
- Great for single-page applications (SPAs)
- Facebook, Instagram, Netflix, Airbnb
In React, components are small, reusable pieces of UI. Think of them like LEGO blocks — each component represents one part of the screen (Navbar, Button, Footer, etc.) and can be reused anywhere in the app.
Example of a Componentfunction Welcome() {
return <h1>Welcome to React</h1>;
}- Welcome is a component.
- It returns UI using JSX.
- You can use it anywhere with
<Welcome />.
JSX stands for JavaScript XML. It lets you write HTML-like code inside JavaScript, making React code easier to read and write. JSX is compiled by Babel into React.createElement() calls.
// Without JSX
const element = React.createElement("h1", null, "Hello World");
// With JSX
const element = <h1>Hello World</h1>;- JSX must have one root element.
- Use
classNameinstead ofclass. - JavaScript expressions go inside
{}.
React has two types of components. Today, developers almost exclusively use Functional Components.
Functional ComponentsSimple JavaScript functions that return JSX. They support hooks.
const Welcome = () => {
return <h1>Hello React</h1>;
};- Functional components use Hooks (useState, useEffect).
- Class components use lifecycle methods (componentDidMount, etc.).
- Functional components are simpler, shorter, and easier to test.
Props (Properties) are used to pass data from a parent component to a child component. They work like function arguments.
function Welcome(props) {
return <h1>Hello {props.name}</h1>;
};
<Welcome name="Akash" />- Props are read-only — the child cannot modify them.
- Use destructuring for cleaner syntax:
function Welcome({ name }) - Any data type can be passed: strings, numbers, arrays, functions, objects.
State is an object that holds component data. When the state changes, React automatically re-renders the component.
State = data that can change over time. Examples: counter value, form input, dark/light mode toggle, login status.
function Welcome({ name }) {
return <h1>Hello {name}</h1>;
};
// State example
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}- State is managed with the
useStatehook in functional components. - Never mutate state directly — always use the setter function.
useState is a React Hook that adds state to functional components, allowing them to store and update data dynamically.
const [state, setState] = useState(initialValue);
// Basic Counter Example
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}state— the current value.setState— function to update the value.initialValue— the starting value.
The Virtual DOM (VDOM) is a lightweight copy of the real HTML DOM kept in memory. React uses it to update the UI efficiently.
How it works- State changes → React creates a new Virtual DOM.
- React compares old VDOM vs new VDOM (diffing).
- Only the changed parts are updated in the real DOM (reconciliation).
- Direct DOM manipulation is slow.
- The Virtual DOM minimises real DOM operations.
- Results in faster, smoother UIs.
Event handling means responding to user actions like clicks, typing, hovering, and form submissions.
function App() {
function handleClick() {
alert("Button Clicked");
}
return (
<button onClick={handleClick}>Click Me</button>
);
}onClick— button clicksonChange— input changesonSubmit— form submissiononMouseEnter / onMouseLeave— hoveronKeyDown / onKeyUp— keyboard
React uses camelCase event names (unlike HTML which uses lowercase).
Conditional rendering means showing different UI based on a condition using regular JavaScript logic.
function App() {
const isLoggedIn = true;
return (
<div>
{isLoggedIn ? <h1>Welcome</h1> : <h1>Please Login</h1>}
</div>
);
}React renders lists using JavaScript's map() method. Every item in a list must have a unique key prop so React can track which items changed.
import { useEffect } from "react";
function App() {
useEffect(() => {
console.log("Component Mounted");
}, []);
return <h1>Hello</h1>;
}- Keys must be unique among siblings.
- Use stable IDs rather than array indexes when possible.
- Keys help React avoid unnecessary re-renders.
A Fragment lets you group multiple elements without adding an extra <div> to the DOM.
// Runs once on mount
useEffect(() => {
console.log("Mounted");
}, []);
// Runs when count changes
useEffect(() => {
console.log("Count changed");
}, [count]);
// Runs on every render
useEffect(() => {
console.log("Runs every render");
});
// Multiple dependencies
useEffect(() => {
console.log("Runs when count or name changes");
}, [count, name]);- Keeps the DOM clean — no unnecessary wrapper divs.
- Short syntax:
<>...</> - Long syntax:
<React.Fragment>...</React.Fragment>
useRef returns a mutable ref object whose .current property persists across renders. It is used to directly access DOM elements or store values that don't trigger a re-render.
// Without lifting state – inputs are out of sync
function Input1() {
const [text, setText] = useState("");
}
function Input2() {
const [text, setText] = useState("");
}
// With lifting state – parent owns the state
import { useState } from "react";
function App() {
const [text, setText] = useState("");
return (
<div>
<Input text={text} setText={setText} />
<Display text={text} />
</div>
);
}
function Input({ text, setText }) {
return (
<input
value={text}
onChange={(e) => setText(e.target.value)}
/>
);
}
function Display({ text }) {
return <h1>{text}</h1>;
}- Accessing DOM nodes (focus, scroll, measure).
- Storing previous state values.
- Holding timer IDs without causing re-renders.
The form input value is managed by React state.
import { useState } from "react";
function App() {
const [name, setName] = useState("");
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<h1>{name}</h1>
</div>
);
}The form input value is managed by the DOM via a ref.
// Uncontrolled input (not recommended)
function App() {
const inputRef = useRef(null);
function handleSubmit() {
alert(inputRef.current.value);
}
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}- Use controlled when you need validation, real-time updates, or form submission handling.
- Use uncontrolled for simple forms or integrating with non-React code.
Every React component goes through three lifecycle phases: Mounting, Updating, and Unmounting. In functional components these are handled by useEffect.
- Mount: Component is added to the DOM.
- Update: State or props change, component re-renders.
- Unmount: Component is removed from the DOM.
useEffect is a React Hook for handling side effects — operations that happen outside normal UI rendering (API calls, timers, DOM manipulation, event listeners).
import { useEffect } from "react";
function App() {
useEffect(() => {
console.log("Component Mounted");
}, []);
return <h1>Hello</h1>;
}- Fetching API data
- Updating the document title
- Timers (setTimeout, setInterval)
- Adding/removing event listeners
- Local storage access
The dependency array is the second argument of useEffect. It controls when the effect runs.
import { useEffect } from "react";
function App() {
useEffect(() => {
console.log("Component Mounted");
}, []);
return <h1>Hello</h1>;
}[]→ run once on mount only.[count]→ run whencountchanges.- no array → run on every render.
[a, b]→ run whenaorbchanges.
Lifting state up means moving shared state to the nearest common parent component so multiple children can access the same data.
// Without lifting state – inputs are out of sync
function Input1() {
const [text, setText] = useState("");
}
function Input2() {
const [text, setText] = useState("");
}
// With lifting state – parent owns the state
import { useState } from "react";
function App() {
const [text, setText] = useState("");
return (
<div>
<Input text={text} setText={setText} />
<Display text={text} />
</div>
);
}
function Input({ text, setText }) {
return (
<input
value={text}
onChange={(e) => setText(e.target.value)}
/>
);
}
function Display({ text }) {
return <h1>{text}</h1>;
}- Parent stores the state.
- Parent passes state down via props.
- Children call the setter to update shared state.
- All components stay synchronized.
A controlled component is a form element whose value is controlled by React state. React is the single source of truth.
import { useState } from "react";
function App() {
const [name, setName] = useState("");
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<h1>{name}</h1>
</div>
);
}- User types.
onChangefires.- State updates.
- React re-renders.
- Input shows the updated value.
- Easy form validation
- Real-time updates
- Better control and debugging
A key is a special prop that helps React identify which list items changed, were added, or removed, enabling efficient updates.
// Without key – React warns
const users = ["Akash", "Rahul", "Aman"];
users.map((user) => <li>{user}</li>);
// With index as key
users.map((user, index) => (
<li key={index}>{user}</li>
));
// Best practice: use unique IDs
const users = [
{ id: 1, name: "Akash" },
{ id: 2, name: "Rahul" },
];
users.map((user) => (
<li key={user.id}>{user.name}</li>
));- Keys must be unique among siblings.
- Use stable IDs over array indexes when possible.
- Missing keys trigger a React warning and can cause bugs.
The Context API lets you share data between components without manually passing props at every level. It solves prop drilling.
import { createContext, useContext } from "react";
const UserContext = createContext();
function App() {
return (
<UserContext.Provider value="Akash">
<Profile />
</UserContext.Provider>
);
}
function Profile() {
const user = useContext(UserContext);
return <h1>Hello {user}</h1>;
}createContext()— create the context.Provider— wrap components that need the data.useContext()— consume the data anywhere in the tree.
Prop drilling is when you pass props through many levels of components just to get data to a deeply nested child, even though intermediate components don't use that data.
// Prop drilling – user passed through every level
function App() {
const user = "Akash";
return <Parent user={user} />;
}
function Parent({ user }) {
return <Child user={user} />;
}
function Child({ user }) {
return <GrandChild user={user} />;
}
function GrandChild({ user }) {
return <h1>{user}</h1>;
}- Hard to maintain and scale.
- Intermediate components become cluttered.
- Context API
- Redux / Zustand
- Component composition
React.memo is a higher-order component that prevents a functional component from re-rendering when its props haven't changed.
// Without memo – re-renders every time parent renders
function Child() {
console.log("Child Rendered");
return <h1>Child</h1>;
}
// With memo – only re-renders when props change
import React, { memo, useState } from "react";
const Child = memo(({ name }) => {
console.log("Child Rendered");
return <h1>{name}</h1>;
});
function App() {
const [count, setCount] = useState(0);
return (
<div>
<Child name="Akash" />
<button onClick={() => setCount(count + 1)}>{count}</button>
</div>
);
}- Wraps a component:
const MemoComp = memo(MyComponent). - React does a shallow comparison of props.
- Best for components that render frequently with the same props.
useCallback memoizes a function so it is not recreated on every render. Useful when passing callbacks to child components wrapped with React.memo.
import { useCallback, useState } from "react";
function App() {
const [count, setCount] = useState(0);
// Without useCallback, handleClick is recreated on every render
const handleClick = useCallback(() => {
console.log("Clicked");
}, []); // recreated only when dependencies change
return (
<div>
<button onClick={handleClick}>Click</button>
<button onClick={() => setCount(count + 1)}>{count}</button>
</div>
);
}- Returns the same function reference unless dependencies change.
- Combine with
React.memofor maximum benefit. - Overusing it adds complexity — only use when there's a real performance issue.
useMemo memoizes a computed value, preventing expensive calculations from running on every render.
import { useState, useMemo } from "react";
function App() {
const [count, setCount] = useState(0);
const [dark, setDark] = useState(false);
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {}
return num * 2;
};
// Recalculates only when count changes
const result = useMemo(() => {
return expensiveCalculation(count);
}, [count]);
return (
<div>
<h1>{result}</h1>
<button onClick={() => setCount(count + 1)}>Count</button>
<button onClick={() => setDark(!dark)}>Theme</button>
</div>
);
}useCallbackmemoizes functions;useMemomemoizes values.- Only recalculates when dependencies change.
- Don't overuse — profiling first is recommended.
useReducer is an alternative to useState for managing complex state logic. It follows the Redux pattern: dispatch an action → reducer returns new state.
import { useReducer } from "react";
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case "increment": return { count: state.count + 1 };
case "decrement": return { count: state.count - 1 };
case "reset": return initialState;
default: return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<h1>{state.count}</h1>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
<button onClick={() => dispatch({ type: "reset" })}>Reset</button>
</div>
);
}- Best when state has multiple sub-values or complex transitions.
- Easier to test (pure function).
- Can replace Redux for local complex state.
Custom hooks are JavaScript functions whose names start with use and that can call other hooks inside. They let you extract and reuse stateful logic across multiple components.
// useFetch.js – custom hook
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
})
.catch((err) => {
setError(err);
setLoading(false);
});
}, [url]);
return { data, loading, error };
}
// Usage in a component
function App() {
const { data, loading, error } = useFetch(
"https://jsonplaceholder.typicode.com/users"
);
if (loading) return <h1>Loading...</h1>;
if (error) return <h1>Error!</h1>;
return (
<ul>
{data.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}- Must start with
use(e.g.useFetch,useForm). - Can use any built-in hook inside.
- Keeps components clean and logic reusable.
An Error Boundary is a class component that catches JavaScript errors anywhere in its child component tree and displays a fallback UI instead of crashing the app.
import React from "react";
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
console.log("Error:", error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
// Usage
function App() {
return (
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
);
}- Only available as class components (no hook equivalent yet).
- Does NOT catch errors in event handlers or async code.
- Wrap around any section of your app to isolate failures.
Portals let you render a child component outside the main DOM hierarchy (e.g. inside #modal-root) while keeping React's event bubbling working normally.
import { createPortal } from "react-dom";
function Modal({ children }) {
return createPortal(
<div className="modal">{children}</div>,
document.getElementById("modal-root") // outside root div
);
}
function App() {
return (
<div>
<h1>Main App</h1>
<Modal>
<p>This renders outside the root!</p>
</Modal>
</div>
);
}- Common uses: modals, tooltips, dropdowns, toasts.
- Events still bubble through the React tree, not the DOM tree.
forwardRef lets a parent component pass a ref through to a child's DOM node or inner component. Normally refs don't pass through function components.
import { forwardRef, useRef } from "react";
// Child exposes its DOM node to parent
const Input = forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
function App() {
const inputRef = useRef(null);
return (
<div>
<Input ref={inputRef} placeholder="Type here" />
<button onClick={() => inputRef.current.focus()}>
Focus
</button>
</div>
);
}- Required when building reusable input/button components that need ref access.
- Combine with
useImperativeHandleto expose custom methods.
Reconciliation is the process React uses to efficiently update the UI when state or props change. React compares the old Virtual DOM with the new one (diffing) and only updates the parts that changed in the real DOM.
How diffing works- If the element type changes, React destroys and rebuilds the subtree.
- If the type is the same, React updates only the changed attributes.
keyprops help React match list items across renders.
A Higher Order Component is a function that takes a component and returns a new enhanced component. HOCs are used to reuse component logic (auth checks, loading states, logging, etc.).
import { useSelector, useDispatch } from "react-redux";
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<h1>{count}</h1>
<button onClick={() => dispatch({ type: "INCREMENT" })}>
Increase
</button>
</div>
);
}- HOCs don't modify the original component — they wrap it.
- Examples:
withRouter,connect()(Redux),withAuth. - Custom hooks are now often preferred over HOCs.
Lazy loading means loading components only when they are needed. React provides React.lazy() for this.
import React, { lazy, Suspense } from "react";
const About = lazy(() => import("./About"));
function App() {
return (
<Suspense fallback={<h1>Loading...</h1>}>
<About />
</Suspense>
);
}- Reduces the initial JavaScript bundle size.
- Must be used with
Suspensefor a fallback UI. - Works with route-level code splitting in Next.js.
Suspense is a React component that handles loading states while waiting for lazy-loaded components or async data to resolve. It shows a fallback UI until the content is ready.
import React, { lazy, Suspense } from "react";
const About = lazy(() => import("./About"));
function App() {
return (
<Suspense fallback={<h1>Loading...</h1>}>
<About />
</Suspense>
);
}- Used with
React.lazy()for code splitting. - In React 18+, also works with data fetching libraries (e.g. Relay, SWR).
- Prevents blank screens during loading.
Redux is a state management library that stores all shared application state in one central store. Any component can read from or dispatch actions to the store.
Redux Data Flow- Component dispatches an action.
- Reducer processes the action and returns new state.
- Store updates.
- UI re-renders.
import { useSelector, useDispatch } from "react-redux";
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<h1>{count}</h1>
<button onClick={() => dispatch({ type: "INCREMENT" })}>
Increase
</button>
</div>
);
}- Large apps with complex shared state.
- Authentication, shopping cart, global theme, user data.
- For simpler cases, Context API + useReducer may be enough.
StrictMode is a development-only tool that helps you find potential problems in your app. It activates additional warnings and checks.
import { StrictMode } from "react";
function App() {
return (
<StrictMode>
<MyComponent />
</StrictMode>
);
}- Detects components with unsafe lifecycle methods.
- Warns about deprecated APIs.
- Detects side effects by intentionally double-invoking functions in dev.
- Does NOT affect the production build.
Concurrent Mode (React 18+) allows React to work on multiple tasks simultaneously, pausing and resuming rendering as needed. This keeps the UI responsive even during heavy computations.
Key featuresuseTransition— marks state updates as non-urgent so React can keep the UI responsive.useDeferredValue— defers updating a value until the browser is idle.startTransition— wraps updates that can be interrupted.
Code splitting is the practice of splitting your JavaScript bundle into smaller chunks that are loaded on demand. This reduces the initial load time.
Methods in ReactReact.lazy()+Suspensefor component-level splitting.- Dynamic
import()for module-level splitting. - Route-based splitting (most common in Next.js — automatic per page).
SSR means the HTML is generated on the server for each request and sent to the browser. This makes the first page load faster and improves SEO.
SSR in Next.jsSSR vs CSR vs SSG- CSR — browser renders; fast navigation, poor SEO.
- SSR — server renders each request; great SEO, slower TTFB.
- SSG — HTML pre-built at build time; fastest, good SEO.
Key techniques to keep React apps fast:
import { useState, useMemo } from "react";
function App() {
const [count, setCount] = useState(0);
const [dark, setDark] = useState(false);
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {}
return num * 2;
};
// Recalculates only when count changes
const result = useMemo(() => {
return expensiveCalculation(count);
}, [count]);
return (
<div>
<h1>{result}</h1>
<button onClick={() => setCount(count + 1)}>Count</button>
<button onClick={() => setDark(!dark)}>Theme</button>
</div>
);
}- React.memo — skip re-renders when props are unchanged.
- useCallback — stable function references for child components.
- useMemo — cache expensive computed values.
- Lazy loading — load components only when needed.
- Virtualisation — render only visible list items (react-window, react-virtual).
- Avoid inline objects/functions in JSX — they create new references every render.
- Concurrent features (React 18) — useTransition, useDeferredValue.
A counter using useState with increase, decrease, and reset.
import { useState, useMemo } from "react";
function App() {
const [count, setCount] = useState(0);
const [dark, setDark] = useState(false);
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {}
return num * 2;
};
// Recalculates only when count changes
const result = useMemo(() => {
return expensiveCalculation(count);
}, [count]);
return (
<div>
<h1>{result}</h1>
<button onClick={() => setCount(count + 1)}>Count</button>
<button onClick={() => setDark(!dark)}>Theme</button>
</div>
);
}Runs code once when the component first mounts.
import { useState, useMemo } from "react";
function App() {
const [count, setCount] = useState(0);
const [dark, setDark] = useState(false);
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {}
return num * 2;
};
// Recalculates only when count changes
const result = useMemo(() => {
return expensiveCalculation(count);
}, [count]);
return (
<div>
<h1>{result}</h1>
<button onClick={() => setCount(count + 1)}>Count</button>
<button onClick={() => setDark(!dark)}>Theme</button>
</div>
);
}Use map() to render arrays as UI elements. Always include a unique key.
import React from "react";
function App() {
const users = ["Akash", "Rahul", "Aman"];
return (
<div>
{users.map((user, index) => (
<h1 key={index}>{user}</h1>
))}
</div>
);
}
export default App;Attach handlers using camelCase event props like onClick, onChange, onSubmit.
import React from "react";
function App() {
function handleClick() {
alert("Button Clicked");
}
return (
<button onClick={handleClick}>Click Me</button>
);
}
export default App;React state controls the input value. Every keystroke updates state via onChange.
import React, { useState } from "react";
function App() {
const [name, setName] = useState("");
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<h1>Hello {name}</h1>
</div>
);
}
export default App;Show different UI based on a condition using the ternary operator.
import React from "react";
function App() {
const isLoggedIn = true;
return (
<div>
{isLoggedIn
? <h1>Welcome User</h1>
: <h1>Please Login</h1>
}
</div>
);
}
export default App;Pass data from a parent to a child using props.
// App.js
import React from "react";
import User from "./User";
function App() {
return (
<div>
<User name="Akash" age={25} />
</div>
);
}
export default App;
// User.js
function User({ name, age }) {
return (
<div>
<h1>{name}</h1>
<p>Age: {age}</p>
</div>
);
}
export default User;Use <>...</> to group elements without adding an extra DOM node.
// Problem – React components must return a single parent
// This throws an error:
function App() {
return (
<h1>Hello</h1>
<p>Welcome</p>
);
}
// Fix with Fragment
import React, { Fragment } from "react";
function App() {
return (
<Fragment>
<h1>Hello</h1>
<p>Welcome</p>
</Fragment>
);
}
// Shorthand <>...</>
function App() {
return (
<>
<h1>Hello</h1>
<p>Welcome</p>
</>
);
}Share data across components without prop drilling.
// App.js
import React from "react";
import UserContext from "./UserContext";
import Home from "./Home";
function App() {
const username = "AK Singh";
return (
<UserContext.Provider value={username}>
<Home />
</UserContext.Provider>
);
}
// Home.js
import Profile from "./Profile";
function Home() {
return (
<div>
<h1>Home Component</h1>
<Profile />
</div>
);
}
// Profile.js – accesses context directly
import { useContext } from "react";
import UserContext from "./UserContext";
function Profile() {
const user = useContext(UserContext);
return <h2>Welcome {user}</h2>;
}Use React.lazy() + Suspense to load a component only when it's needed.
import React, { lazy, Suspense } from "react";
// Lazy load the component
const About = lazy(() => import("./About"));
function App() {
return (
<Suspense fallback={<h1>Loading...</h1>}>
<About />
</Suspense>
);
}
export default App;