Re-rendering Components in ReactJS
In ReactJS re-rendering occurs when React needs to update the app with new data or when a component’s state or props change. React compares the updated component with the previous one and updates only the parts that need changing to keep everything in sync.
Re-rendering occurs under the following scenarios:
- State and Props: Re-rendering components in ReactJS happens when their state or the props change.
- Virtual DOM: React uses the concept of the virtual DOM to compare the current state of the UI with the new state and then updates only the necessary part.
- Component Lifecycle: Re-renders in class components are controlled by lifecycle methods, while hooks manage them in functional components.
- Force Update: You can force a re-render using forceUpdate() in class components, though this is rarely needed.
How React Handles Re-Rendering?
React uses a Virtual DOM as an intermediate layer. It sits between what the developer wants to show on the screen and what the browser actually renders. This helps React efficiently update only the necessary parts of the UI.
- Initial Render: React creates a virtual DOM tree representing the UI based on the current state and props of components.
- State or Props Change: When the state or props change, React updates the component’s virtual DOM and compares it with the previous virtual DOM using a process called reconciliation.
- Diffing Algorithm: React’s diffing algorithm identifies the differences between the current and previous virtual DOM. Only the changes are applied to the real DOM, which minimizes performance overhead.
- Re-rendering: React re-renders the components with the new state or props, and only the necessary DOM updates are applied.
Example: React Re-rendering with State
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
Output

In this example
- Initially the component rerenders with the count = 0.
- When we click the button the state updates, which trigger the re-rendering.
- Now, the React will compare with the virtual Dom and will update the only changed part.
When Does React Re-render a Component?
Re-rendering components in React happens when
- State Change: Using setState in class components or useState in functional components triggers a re-render.
const [count, setCount] = useState(0);const increment = () => setCount(count + 1);
- Props Changes: When a parent component passes new props to a child, the child component re-renders.
<ChildComponent value={newValue} />
- Force Update: Although rarely needed, you can force a re-render using forceUpdate() in class components.
this.forceUpdate();
Context Changes: Components consuming context via useContext will re-render when the context value changes.
const value = useContext(MyContext);
Identifying Unnecessary Re-renders
Due the unnecessary re-renders the can slow the performance. So, we can identify them by using below methods:
- React Developer Tools Profiler: It shows the re-rendering of the component.
- Console Logs: It helps to track the renders inside the render function.
How React Optimizes Re-rendering?
React optimizes re-rendering using several techniques to ensure performance:
- Virtual DOM: React maintains a lightweight virtual DOM that helps minimize direct DOM manipulations.
- Diffing Algorithm: React compares the new virtual DOM with the previous version to detect changes efficiently.
- Batched Updates: React batches multiple state updates together to reduce the number of re-renders.
- Memoization: React provides tools like React.memo and useMemo to prevent unnecessary re-renders.
How to Control Re-rendering in React
Controlling unnecessary re-renders is essential for optimizing performance, especially in large applications. Here are some techniques to manage re-rendering
1. React.memo
React.memo
is a higher-order component (HOC) that can be used to wrap functional components to prevent unnecessary re-renders. It only re-renders if the props change, similar to how PureComponent
works for class components.
const MyComponent = React.memo((props) => {
return <div>{props.name}</div>;
});
2. shouldComponentUpdate
The shouldComponentUpdate lifecycle method allows you to control whether a component should re-render or not. By returning false in shouldComponentUpdate, you can prevent re-renders even when state or props change.
class MyComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// Perform custom comparison and return true/false
return nextState.someValue !== this.state.someValue;
}
render() {
return <div>{this.state.someValue}</div>;
}
}
3. useMemo
useMemo is a React Hook that memorizes the result of a computation and returns the cached result unless its dependencies have changed. This is useful to prevent expensive calculations from running on every render.
const compute = useMemo(() => {
return val(props);
}, [props.someDependency]);
4. useCallback
useCallback is similar to useMemo, but it returns a memoized version of the callback function. This ensures that the same function reference is passed on re-renders unless its dependencies change.
const memoizedCallback = useCallback(() => {
}, [props.someDependency]);
5. Lazy Loading and Suspense
React's lazy loading and Suspense allow you to load components only when they are required. This can help reduce the number of re-renders during initial loading by splitting the bundle into smaller chunks.
const LazyComp = React.lazy(() => import('./LazyComponent'));
function MyComp() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComp />
</Suspense>
);
}