It is an optimization technique used to improve performance by caching the results of expensive function calls or avoiding unnecessary re-renders of components.
How to use memoization effectively in React Native:
- Memoizing Components with React.memo React.memo is used to prevent unnecessary re-renders of functional components when their props do not change.
import React from 'react';
const ExpensiveComponent = React.memo(({ data }) => {
console.log('Rendering ExpensiveComponent');
return <Text>{data}</Text>;
});
// Parent component
const App = () => {
const [count, setCount] = React.useState(0);
return (
<>
<ExpensiveComponent data="This won't re-render" />
<Button title="Increment" onPress={() => setCount(count + 1)} />
</>
);
};
In this example, ExpensiveComponent only re-renders if its data prop changes.
2.Memoizing Values with useMemo
useMemo caches the result of an expensive computation so that it does not need to be recalculated unless its dependencies change.
import React, { useMemo } from 'react';
const App = () => {
const [count, setCount] = React.useState(0);
const expensiveCalculation = useMemo(() => {
console.log('Performing expensive calculation');
return count * 2;
}, [count]);
return (
<>
<Text>Result: {expensiveCalculation}</Text>
<Button title="Increment" onPress={() => setCount(count + 1)} />
</>
);
};
3.Memoizing Functions with useCallback
useCallback memoizes a function to avoid re-creating it on every render, especially when passing it as a prop to child components.
import React, { useState, useCallback } from 'react';
const Button = React.memo(({ onPress }) => {
console.log('Rendering Button');
return <TouchableOpacity onPress={onPress}><Text>Press Me</Text></TouchableOpacity>;
});
const App = () => {
const [count, setCount] = useState(0);
// without useCallback the onPress prop changed (new function reference), so I need to re-render <Button />
const increment = useCallback(() => {
setCount(prev => prev + 1);
}, []);
return (
<>
<Text>Count: {count}</Text>
<Button onPress={increment} />
</>
);
};
Without useCallback, the increment function would be re-created on every render, causing the Button component to re-render unnecessarily.
The problem without useCallback
In React, functions are objects.
Every time your component re-renders, any inline function you create gets a new reference in memory even if the logic is identical.
Avoid Overusing Memoization
- Avoid memoizing components or values that are inexpensive to compute.
- Use profiling tools (e.g., React DevTools Profiler) to identify performance bottlenecks before applying memoization.
Memoization Libraries
In some cases, you might want to use libraries like memoize-one or lodash.memoize for custom memoization needs:
import memoize from 'lodash.memoize';
const memoizedFunction = memoize(expensiveFunction);
function expensiveFunction(arg) {
console.log('Calculating...');
return arg * 2;
}
console.log(memoizedFunction(2)); // "Calculating..." -> 4
console.log(memoizedFunction(2)); // Cached result -> 4
lodash.memoize keeps a cache of results for each unique input key you pass in.
useMemo (React) doesn’t store results for every input ever passed.
It only remembers the last computation tied to its dependency array.
What memoization does under the hood
- When you use React.memo, useMemo, or useCallback, React has to:
- Store the previous value (or component render).
- Compare the current props/values with the previous ones (a shallow comparison).
- Decide whether to re-render or return the cached result.
This bookkeeping work itself takes CPU time and memory.
If the component or calculation is very cheap (e.g., rendering a single or calculating a + b), then:
Re-rendering or recalculating is often faster than doing all the memoization checks.
Adding memoization in such cases can slow things down instead of speeding them upAlways measure (with React DevTools Profiler) before and after, to confirm the performance gain.
Top comments (0)