An assistant over my own record. It knows my work, my writing, my stack and the resources I keep. It does not know anything else, and it will say so.
If you're anything like me, you love how smooth React can be... until it isn't! Yep, as your app grows and becomes more complex, you might start noticing some performance slowdowns. But fear not! React gives us a couple of awesome tools useMemo and useCallback to keep things running fast and smooth.
In this guide, we’ll break down these two hooks in a fun, friendly way, so you can optimize your app without breaking a sweat!
Great question! React is usually blazing fast. But sometimes, if you’re running expensive calculations or passing a lot of functions through your component tree, things can start to drag a bit. Every time your app re-renders (because props or state changed), React has to re-do a lot of stuff.
That’s where useMemo and useCallback come in. They basically let React “remember” stuff so it doesn’t have to re-do unnecessary work!
useMemo: Making React Remember the Hard Stuff!
Think of useMemo as a smart assistant. It keeps track of the result of a function and only recalculates it if something important changes. Why bother re-doing a calculation when the inputs haven’t even changed? Exactly.
const memoizedValue = useMemo(() => {
return calculateSomethingExpensive(a, b);
}, [a, b]);
In this example, calculateSomethingExpensive will only run if a or b change. Otherwise, React says, "No need to redo that work — I’ve got it saved right here!"
Let’s say we’re building a component that calculates the total value of a shopping cart. Every time the component re-renders, it recalculates that total. Now, if you’re shopping a lot (which we all do!), this calculation might slow down the app:
function ShoppingCart({ items }) {
const totalValue = items.reduce((sum, item) => sum + item.price, 0);
return <div>Total: {totalValue}</div>;
}
Even if the items haven’t changed, we’re still doing the math every time! With useMemo, we can tell React to only recalculate when the items array changes:
function ShoppingCart({ items }) {
const totalValue = useMemo(() => {
return items.reduce((sum, item) => sum + item.price, 0);
}, [items]);
return <div>Total: {totalValue}</div>;
}
Boom! Now your app only recalculates when there’s actually something new in your cart. It’s like React saying, “I’ve got this covered.”
useCallback: No More New Functions Every Second!
Now let’s talk about useCallback. If useMemo is about remembering values, useCallback is about remembering functions. This is super useful when you’re passing a function as a prop to a child component.
Without useCallback, React recreates your function on every render — this can cause your child components to re-render unnecessarily. And we all know how annoying that can be!
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
This tells React to only recreate the doSomething function if a or b change. If not, React just reuses the previous function!
Here’s a common scenario: You have a parent component passing down a handleClick function to a child component. But every time the parent re-renders, the function gets recreated, forcing the child to re-render too:
function ParentComponent() {
const handleClick = () => {
console.log('Button clicked!');
};
return <ChildComponent onClick={handleClick} />;
}
Even if nothing has changed, the child component thinks it needs to re-render because the handleClick function is "new" every time.
Now, let’s be clever and use useCallback to avoid this:
function ParentComponent() {
const handleClick = useCallback(() => {
console.log('Button clicked!');
}, []);
return <ChildComponent onClick={handleClick} />;
}
Tada! Now the handleClick function only changes if its dependencies change, and the child component doesn’t re-render unnecessarily.
useMemo vs. useCallback: What’s the Difference? (Spoiler: Both are Awesome!)
Okay, so now you’re probably thinking, “These two sound pretty similar—what’s the difference?”
useMemo: Caches the result of a function. It’s great when you have some expensive calculation that doesn’t need to be recalculated all the time.useCallback: Caches the function itself. Perfect when you’re passing functions down as props and want to avoid unnecessary re-renders.useMemo to avoid recalculating something unless it’s necessary.useCallback to prevent creating new functions unless their dependencies have changed.Here’s the golden rule: Don’t overuse useMemo and useCallback. Seriously! React is already fast enough for most apps, and using these hooks everywhere can add unnecessary complexity.
When to Use useMemo:
When to Use useCallback:
React.memo).Measure performance before and after using these hooks. If you notice a speed boost, great! If not, maybe it’s not worth the extra complexity.
useMemo or useCallback on every single function or calculation. It can actually hurt performance if used excessively. Only memoize when you need to.So there you have it! useMemo and useCallback are awesome tools to keep your React app snappy, but remember—React is already super fast. Use these hooks when you need to optimize performance, but don’t go overboard. Simplicity is key!
With that, go out there and make your app lightning-fast (and have fun while doing it)