How to Optimize Components and Prevent Unnecessary Re-Renders

kietHTkietHT
2 min read

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.

0
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.