Let's think about it this way for a second
React.memo(Component) skips re-rendering a component when its props haven't changed — this prevents every child component from automatically re-rendering whenever the parent re-renders. useMemo(calculation, deps) caches the result of an expensive calculation and returns the cached value instead of recomputing it when the dependencies haven't changed. useCallback(function, deps) keeps a function reference stable — useful when passing a function as a prop to a React.memo child (if the function reference isn't stable, React.memo stops working).
Let's connect this to a real-world scenario
If a FlatList's renderItem function creates a brand-new inline function ({item} => ...) on every component render, React.memo on the child item component won't help at all — you need to keep the renderItem function stable with useCallback. Don't optimize prematurely — profile first once there's an actual problem ('the app feels sluggish'), then do targeted optimization.
Code Example
import { memo, useCallback, useMemo } from 'react';
const ProductCard = memo(function ProductCard({ product, onPress }) {
console.log('Rendering:', product.name); // memo ရှိရင် unnecessary re-render တွေ မဖြစ်
return <Text onPress={() => onPress(product.id)}>{product.name}</Text>;
});
function ProductList({ products }) {
// Stable function reference — ProductCard memo ကို အလုပ်ဖြစ်စေဖို့
const handlePress = useCallback((id) => {
console.log('Pressed:', id);
}, []);
const sortedProducts = useMemo(
() => [...products].sort((a, b) => a.price - b.price),
[products],
);
return sortedProducts.map((p) => (
<ProductCard key={p.id} product={p} onPress={handlePress} />
));
}In the console log, you'll see that the ProductCard component only re-renders when the products data changes (the 'Rendering: ...' log shows up less often).Try it in 5 minutes
Run a list component with a console.log both without and with React.memo, and observe the difference in re-render count.
A quick word of caution
Sprinkling performance optimization everywhere without an actual measured problem raises code complexity and can even increase bug risk — find the bottleneck first with React DevTools Profiler, then optimize.