How to Optimize Components and Prevent Unnecessary Re-Renders
let's dive in. you're probably already using hooks with that version, right? good. here’s how you can tackle it.
1. Use React.memo
for Functional Components
If you’ve got functional components that are re-rendering unnecessarily because of unchanged props, you can wrap them in React.memo
. This memoizes the component, preventing re-renders when the props don't change.
const ExpensiveComponent = React.memo(({ data }) => {
// only re-renders if 'data' changes
return <div>{data}</div>;
});
2. Use useMemo
to Memoize Expensive Calculations
If you have calculations inside a component that don’t need to be recalculated on every render, you can use useMemo
to memoize them. This saves performance by recalculating values only when their dependencies change.
const MemoizedValue = useMemo(() => expensiveCalculation(data), [data]);
3. Use useCallback
for Stable Function References
When you pass functions down to child components, if those functions get re-created on every render, it can trigger unnecessary re-renders. Use useCallback
to memoize those functions and keep the same reference.
const handleClick = useCallback(() => {
// do something
}, [dependency]);
4. Consider React Context
for Global State
Instead of passing state down multiple levels via props (which triggers re-renders), use React Context
to avoid prop drilling. Just be cautious, though—if you use it improperly, it can cause too many renders as well.
const AppContext = createContext();
const Parent = () => {
const [state, setState] = useState();
return (
<AppContext.Provider value={{ state, setState }}>
<Child />
</AppContext.Provider>
);
};
5. Avoid Inline Functions/Objects
Inline functions and objects get recreated on every render, and that causes unnecessary re-renders. So, you should always define your functions outside of the JSX.
// Avoid this
<Button onClick={() => handleClick()}/>
// Do this
const handleClick = () => { /* your logic */ };
<Button onClick={handleClick}/>
6. Optimize State Updates with Functional Updates
When updating state based on the previous state, use functional updates to avoid unnecessary re-renders.
setState(prev => prev + 1); // instead of setState(state + 1)
7. Lazy Loading and Code Splitting
If you have heavy components that don’t need to be loaded immediately, use React.lazy
and Suspense
to load them only when necessary.
const LazyComponent = React.lazy(() => import('./LazyComponent'));
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
Conclusion:
There are plenty of ways to optimize performance in React. The key here is identifying what triggers re-renders and when. With these techniques, you'll be able to handle it without bottlenecking your app like a noob.
Subscribe to my newsletter
Read articles from kietHT directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
kietHT
kietHT
I am a developer who is highly interested in TypeScript. My tech stack has been full-stack TS such as Angular, React with TypeScript and NodeJS.