In React, useMemo is a React hook used for memoizing values, particularly expensive computations or calculations, to optimize performance in functional components.
It memoizes the result of a function and returns the memoized value, avoiding unnecessary recalculations when the component re-renders.
It's used with `React.memo` for components to prevent re-rendering. it performs a swallow comparison between the `previous` and `next` props.
It memoizes the computed value so that if the dependencies remain the same between re-renders, useMemo Hook returns the same memoized value without re-computing it, improving performance.
It Provides flexibility in memorising any type of value, not just React components, making it a versatile tool for optimizing various computations and calculations in our React components.
We can re-compute memorized value on Selective dependencies, we can control when the memoized value should be re-computed, allowing us to optimize the performance of expensive calculations.
It takes two arguments: the first argument as a function and the second argument as an array of dependencies. The function contains the computation we want to memoize, and the dependencies are the values that, when changed, will trigger the re-computation of the memoized value.
import React, { useState, useMemo } from 'react'; const YourComponent = () => { const [count, setCount] = useState(1000); // With useMemo: Memoizes the result, recalculates only if dependencies (count) change const expensiveCalculation = () => { let sum = 0; for(let i =0; i<count; i++) { sum += i; } return sum; }; const memoizedValue = useMemo(() => expensiveCalculation(), [count]); return ( <div> <p>Count: {count}</p> <p>Result: {memoizedValue}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); }; export default YourComponent;
import React, { useState, useMemo } from 'react'; import ChildComponent from "./ChildComponent"; export const App = () => { const [count, setCount] = useState(1000); const [notPassToChild, setNotPassToChild] = useState(1); const handleOtherUpdate = () => { setNotPassToChild(notPassToChild + 1) }; // Without useMemo: Expensive calculation runs on every render // const expensiveCalculation = () => { // // Some time-consuming operation // console.log('Calculating...'); // return count * 2; // }; // With useMemo: Memoizes the result, recalculates only if dependencies (count) change const memoizedValue = useMemo(() => { // Some time-consuming operation console.log('Calculating...'); return count * 500; }, [count]); return ( <div> <button onClick={() => handleOtherUpdate()}>Other Updates</button> <p>Count: {count}</p> {console.log("Parent Render")} <button onClick={() => setCount(count + 1)}>Increment</button> <ChildComponent totalAmount={memoizedValue} /> </div> ); };
If you click on the button `Other Updates`, you won't see a new log message in the console `Child Render`.
if we click on the `Increment` button, then it will update the `count` value and `count` is passed as a dependency to `memoizedValue` useMemo function, so it will reevaluate and assign a new value to `memoizedValue` function and it will trigger `ChildComponent` to re-render because props have been changed now.
import React, { memo } from 'react'; const ChildComponent = (props) => { return ( <div> <p>Total Amount: {props?.totalAmount}</p> </div> ); }; export default memo(ChildComponent);
The `expensiveCalculation` function would be invoked on every render of `YourComponent`, even if the count state hasn't changed.
This can be inefficient for expensive calculations.
the `memoizedValue` is memoized, and the result is only recalculated if the dependencies specified in the second parameter of `useMemo` (in this case, the `count` state) change.
This helps optimize the performance by avoiding unnecessary recalculations.