Understanding the React Rendering Lifecycle
While React's rendering pipeline is fast by default, complex component trees can suffer from unnecessary re-renders. When a parent component's state changes, all child components re-render recursively unless optimization boundaries are explicitly defined.
Fundamental Performance Golden Rules
- Wrap expensive calculation logic inside the
useMemohook to memoize computed values. - Pass callback functions to child components wrapped in
useCallbackto maintain referential equality across renders. - Keep state local by isolating state declarations to the lowest possible component in the UI hierarchy.
- Use
React.lazyandSuspensefor code-splitting heavy modals or secondary pages.
Code Example: Optimizing Large List Items
import React, { memo } from 'react';
interface ListItemProps {
item: string;
onSelect: (item: string) => void;
}
const ListItem = memo(({ item, onSelect }: ListItemProps) => {
console.log('Rendering:', item);
return (
<div onClick={() => onSelect(item)} className="list-item">
{item}
</div>
);
});
Wrapping child components with memo() ensures re-rendering only occurs when props actually change, preventing wasteful render cycles when parent list components update.