- Published on
React Js Basic Questions and Answers
- Authors
- Name
- Ganesh Negi
React Js Basic Questions and Answers

1. What is the difference between React Node, Element, and Component ?
React Node, Element, and Component are three core building blocks in React.
- Node: In React, a Node refers to anything that can be rendered, including elements, strings, numbers, or even null.
const stringNode = 'Hello, Interview PI!';
const numberNode = 123;
const booleanNode = true;
const nullNode = null;
const elementNode = <div>Hello, Interview PI!</div>;
- Element: A React Element is a simple object that represents either a DOM node or a component. It defines what should appear on the screen and is immutable by nature, serving as the building block for creating React components.
const element = <div className="greeting">Hello, Interview PI!</div>;
// Using React.createElement
const element = React.createElement(
'div',
{ className: 'greeting' },
'Hello, Interview PI!',
);
Component: A component is a reusable unit of the user interface that can include one or more elements.
Components can be written as functions or classes, accept inputs known as props, and return React elements that specify what should be rendered on the screen.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
2. What are React Fragments used for?
React Fragments: In React 16.2, Fragments were introduced to make it easier to group multiple elements without adding extra tags to the page.
Instead of wrapping everything in a div, you can use a Fragment to keep your code neat and your HTML cleaner.
It’s a simple way to return multiple elements from a component without messing up the structure of your page.
function App() {
return (
<>
<Header />
<Main />
<Footer />
</>
);
}
In this example, the <>...</> syntax is just a shortcut for using a React Fragment.
It lets you group the Header, Main, and Footer components together without adding
an extra <div> to the page.
3. What is the purpose of the key prop in React?
In React, the key prop is like an ID tag for elements in a list.
It helps React keep track of each item, so when something changes, it knows exactly what to update, add, or remove.
This makes the whole rendering process faster and keeps your app running smoothly.
Why Keys Are ImportantEfficient updates: Keys help React quickly figure out which items in a list have changed, been added, or removed. This way, it only updates what’s needed instead of re-rendering everything.
Avoiding bugs: Without unique keys, React might mix up elements when re-rendering, which can cause weird bugs or unexpected behavior in your app.
Better performance: Using proper keys keeps the number of changes to the DOM as small as possible, making your app faster and smoother.
How to Use the Key PropWhen you’re rendering a list in React, make sure to give each item a unique key. The key should stay the same every time the list is rendered. A good choice for a key is something like a unique id from your data — something that doesn’t change.
const items = [
{ id: 1, value: 'Item 1' },
{ id: 2, value: 'Item 2' },
{ id: 3, value: 'Item 3' },
];
function ItemList() {
return (
<ul>
{items.map((item) => (
<ListItem key={item.id} value={item.value} />
))}
</ul>
);
}
function ListItem({ value }) {
return <li>{value}</li>;
}
Using array index as a key: It might seem easy to just use the array index as the key, but it’s a bad idea. If the list changes — like items are added, removed, or reordered — the index can change too, causing React to mix things up and leading to bugs.
Non-unique keys: Always make sure each key is truly unique. If you use duplicate keys, React can get confused about which item is which, and you might see strange bugs or unexpected behavior.
// Bad practice: using array index as key
{
items.map((item, index) => <ListItem key={index} value={item.value} />);
}
// Good practice: using a unique identifier as key
{
items.map((item) => <ListItem key={item.id} value={item.value} />);
}
4. What Happens If You Use Array Indices as Keys in React?
Using array indices as keys in React can cause performance problems and weird bugs. React relies on keys to keep track of elements and know which ones changed.
If you use an index as the key, and the list gets updated (like adding, removing, or reordering items), React might get confused and mix things up, because the keys aren’t stable.
This can lead to elements being incorrectly updated or rendered.
function App() {
const items = ['A', 'B', 'C'];
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
If you add or remove items from the array, React might not update the DOM properly if you're using the index as the key.
That’s because the positions change, but the keys don’t stay consistent. To avoid this problem, it’s better to use unique IDs or any stable value that doesn’t change between renders.
5. What is the difference between Controlled and Uncontrolled React components?
Controlled vs Uncontrolled Components in React
Controlled Components: In controlled components, React takes charge of the form data. The input’s value is tied directly to React state, and any changes to the input go through React event handlers.
This gives you more control over the input, allowing you to validate or modify the data before updating the state.
Uncontrolled Components: In uncontrolled components, React doesn’t manage the form data directly. Instead, the DOM controls the input value.
You can access the input's value using a ref, and it's useful when integrating with third-party libraries or when you need to access the input's value directly, without relying on React state.
Example of controlled component:
function ControlledInput() {
const [value, setValue] = React.useState('');
return (
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
}
Example of uncontrolled component:
function UncontrolledInput() {
const inputRef = React.useRef();
return <input type="text" ref={inputRef} />;
}
6. How would you lift the state up in a React application, and why is it necessary?
Lifting State Up in ReactLifting state up means moving the state from a child component to their closest common parent.
This pattern is useful when you need to share data between components that aren’t directly related as parent and child.
By lifting state up, you can avoid passing props through many layers (called prop drilling) and make managing shared data simpler.
const ParentComponent = () => {
const [counter, setCounter] = useState(0);
return (
<div>
<Child1 counter={counter} />
<Child2 setCounter={setCounter} />
</div>
);
};
const ChildComponent1 = ({ counter }) => <h1>{counter}</h1>;
const ChildComponent2 = ({ setCounter }) => (
<button onClick={() => setCounter((prev) => prev + 1)}>Increment</button>
);
7. What are Pure Components?
Pure Components are a special type of React component that helps improve performance.
They either extend React.PureComponent or use React.memo to avoid unnecessary re-renders.
Pure Components compare their props and state using a shallow comparison (just checking if the values are the same), and if nothing has changed, React skips re-rendering the component, making things faster.
Pure Components are great for situations where the component always renders the same output for the same input and doesn’t rely on external state or side effects.
By using them, you can prevent unnecessary re-renders and keep your React app running efficiently.
8. What is the role of PropTypes in React?
PropTypes in React
PropTypes is a library that helps you check the types of props passed into your components.
With PropTypes, you can define what kind of data a component should expect, and if something's wrong, React will show a warning in the console.
Using PropTypes is a great way to document your components, catch bugs early, and make sure your components get the right kind of data.
import PropTypes from 'prop-types';
const Greeting = ({ name }) => <h1>Hello, {name}!</h1>;
Greeting.propTypes = {
name: PropTypes.string.isRequired,
};
In this example, the Greeting component expects a prop called name, and it must be a string.
If you forget to pass name or pass something that's not a string, React will show a warning in the console to let you know.
9. What are stateless components?
Stateless components don’t have their own memory to store data. They just take information from props and show it on the screen. Their main job is to display the UI based on the data they get.
Stateless components do not manage internal state.
function StatelessComponent({ msg }) {
return <div>{msg}</div>;
}
10. What are stateful components?
Stateful components keep track of their own data (called state) and can change what they show on the screen when something happens, like a user clicking a button or typing in a box.
function StatefulComponent() {
const [count, setCount] = React.useState(0);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
11. Why we using hooks in React?
Hooks let you use features like state and side effects in React functional components, so you don’t need to use class components.
They make your code simpler, easier to read, and allow you to reuse logic in different parts of your app.
Some common hooks are useState for managing data and useEffect for handling things like fetching data or reacting to changes.
Read more for hooks
12. What is the difference between useEffect and useLayoutEffect in React?
useEffect runs after the screen is updated and shown to the user. It’s used for things like data fetching or setting timers—tasks that don’t need to block the screen from showing.
It runs asynchronously, after the DOM is done rendering.
useLayoutEffect runs right after the DOM updates but before the screen is shown.
It’s used when you need to measure or change the layout immediately, like adjusting element sizes.
It runs synchronously to ensure everything is ready before the user sees it.
In most situations, you should use useEffect because it's fast and doesn't block the screen from showing.
Only use useLayoutEffect if you need to make changes to the DOM right away, before the screen updates, like when measuring layout or fixing visual glitches.
import React, { useEffect, useLayoutEffect, useRef } from 'react';
function Example() {
const ref = useRef();
useEffect(() => {
console.log('useEffect: Runs after DOM paint');
});
useLayoutEffect(() => {
console.log('useLayoutEffect: Runs before DOM paint');
console.log('Element width:', ref.current.offsetWidth);
});
return <div ref={ref}>Hello</div>;
}
13. What does the dependency array of useEffect affect?
The dependency array in useEffect tells React when to run the effect.
If the values inside the array change, the effect runs again. If the array is empty ([]), the effect runs only one time—right after the component first shows on the screen.
useEffect(() => {
// Effect code
}, [value1,value2,value3]);
In this example, the effect will run every time value1 or value2 or value3 changes. If you use an empty array ([]) instead, the effect will run only once—right after the component first renders. If you leave out the dependency array completely, the effect will run after every render.
14. What is the useRef hook in React and when should it be used?
The useRef hook in React lets you create a value that stays the same between re-renders.
You can use it to keep a reference to a DOM element (like an input box), manage focus, or store data that you don’t want to cause the component to re-render when it changes.
function TextInputWithFocusButton() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus();
};
return (
<>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Focus Input</button>
</>
);
}
In this example, inputRef holds a reference to the input element. When the button is clicked, the handleClick function uses that reference to set the focus on the input box. This lets you directly interact with the DOM element using useRef.
15. Why does React recommend against mutating state?
React advises against directly changing state because it can cause issues where the UI doesn't match the state of the app.
If you mutate state directly, React might not notice the change, and the UI could get out of sync.
To avoid this, always use the setState function or hooks like useState to update state so React can track and re-render the component correctly.
16. Why does React recommend against mutating state?
React discourages directly mutating state because it can cause unpredictable behavior and bugs.
If you change the state directly, React might not detect those changes, which can cause the UI to be out of sync with the app’s state.
To ensure proper updates, always use the setState function or hooks like useState to update state so React can track changes and re-render the UI accordingly.
17. What is reconciliation in React?
Reconciliation is how React updates the DOM to reflect changes in a component's state or props.
React compares the old virtual DOM with the new one and figures out the smallest set of changes needed to update the actual DOM.
This process is crucial for optimizing performance, reducing unnecessary DOM manipulations, and ensuring efficient rendering.
18. What is hydration in React?
Hydration is the process where React connects event listeners and updates the DOM on the client side to match the virtual DOM.
This is especially important for server-side rendered (SSR) React applications to ensure the content on the client is interactive and consistent with the server-rendered content.
During hydration, React compares the server-rendered HTML with the virtual DOM and updates the client-side DOM to match the virtual DOM structure, making the app interactive.
19. Explain higher-order components (HOCs).
Higher-order components (HOCs) are functions that take a component as input and return a new component with added functionality.
They are useful for reusing code, adding extra props or behaviors, and abstracting common logic in a way that can be shared across multiple components.
const withLogger = (WrappedComponent) => {
return (props) => {
console.log('Component rendered:', WrappedComponent.name);
return <WrappedComponent {...props} />;
};
};
const EnhancedComponent = withLogger(MyComponent);
In this example, the withLogger HOC logs the name of the component each time it renders. The EnhancedComponent is a new component created by the HOC, which includes the logging feature along with the original functionality of the component it wraps.
20. What are some common performance optimization techniques in React?
Some common performance optimization techniques in React include:
Memoization: Use useMemo and useCallback to store results of expensive computations or functions and prevent unnecessary re-renders.
Code Splitting: Break your app into smaller bundles that load dynamically, reducing the initial load time and improving performance.
Lazy Loading: Load components or resources only when they are needed, which reduces the initial loading time and speeds up the user experience.
Virtualization: Render only the elements visible in the viewport (e.g., using windowing or infinite scrolling) to improve performance when dealing with large lists or tables.
Server-Side Rendering (SSR): Pre-render React components on the server, sending the HTML to the client, which can improve the time to first paint and make the app feel faster.
21. What is useReducer Hook in React?
The useReducer hook in React is used to handle complex state logic in functional components.
It’s an alternative to useState and allows state updates based on the current state and an action.
useReducer is ideal for managing state transitions that involve more complicated logic than simple state updates, making it easier to manage complex state changes.
const initialState = { count: 0 };
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
};
const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
};
In this example, the useReducer hook is used to manage the state of a counter component. The state changes are handled based on different actions, like incrementing or decrementing the counter, allowing for more control over the state transitions.
22 How do you test a React application?
Testing React applications can be done using Jest and React Testing Library.
Jest is the testing framework that runs the tests, while React Testing Library provides tools to test components in a way that mimics how users interact with them, ensuring that the tests focus on the user experience rather than implementation details.
23. What is server-side rendering (SSR)?
Server-side rendering (SSR) is a technique where React components are pre-rendered on the server, and the HTML is sent to the client.
This improves performance by reducing the time it takes for the content to appear on the screen (time to first paint) and helps make the content more accessible to search engines and users with slow internet connections.
24. What is Static site generation (SSG)?
Static Site Generation (SSG) is a technique where HTML pages are pre-rendered at build time.
This means that static HTML files are created for each page of a website and can be served directly to users, without needing server-side rendering.
SSG enhances performance, lowers server load, and simplifies hosting and deployment by delivering ready-to-go static content.
25. What is lazy loading in React ?
Lazy loading is a technique where components or resources are loaded only when they are needed, rather than all at once. This helps improve the initial load time of your application by delaying the loading of non-essential components until they are actually required. In React, you can use the React.lazy function to dynamically import components, and the Suspense component to handle loading states while the component is being fetched.
26. What is the purpose of the useContext hook in React ?
The useContext hook in React allows you to access the value of a context provider directly within a functional component. It simplifies consuming context values by eliminating the need for a consumer component. useContext is particularly useful for accessing global data or settings in your app without having to pass props through every level of the component tree.
const ThemeContext = React.createContext('light');
const ThemeProvider = ({ children }) => {
return <ThemeContext.Provider value="dark">{children}</ThemeContext.Provider>;
};
const ThemeConsumer = () => {
const theme = React.useContext(ThemeContext);
return <div>Theme: {theme}</div>;
};
27. What is the purpose of the useMemo hook in React ?
The useMemo hook in React is used to optimize performance by memoizing expensive computations. It caches the result of a function to prevent unnecessary recalculations and re-renders. useMemo takes a function and an array of dependencies as arguments and returns the cached value. The value is only recomputed when one of the dependencies changes.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
28. What is the purpose of the useCallback hook in React?
The useCallback hook in React is used to memoize callback functions, helping prevent unnecessary re-renders of components that depend on those functions. It takes a function and an array of dependencies, and returns a memoized version of the function. The memoized function is recalculated only when one of the dependencies changes.
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
In this example, the doSomething function is memoized using useCallback, meaning the memoized version of the function is cached. This cached function will only be recalculated when either the a or b dependencies change, preventing unnecessary re-renders and optimizing performance.
29. What is the purpose of the useImperativeHandle hook in React?
The useImperativeHandle hook in React is used to customize the instance value that is exposed to parent components when using React.forwardRef. It lets you specify which properties or methods of a child component's instance should be accessible to the parent via a ref, allowing for more control over what is exposed. This is useful when you want to limit or customize the functionality available to parent components.
const ChildComponent = React.forwardRef((props, ref) => {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
}));
return <input ref={inputRef} />;
});
const ParentComponent = () => {
const childRef = useRef(null);
const handleClick = () => {
childRef.current.focus();
};
return (
<>
<ChildComponent ref={childRef} />
<button onClick={handleClick}>Focus Input</button>
</>
);
};