import React, { memo, useMemo, useState } from 'react'
const Heading = memo(({ style, title }) => {
console.log('Rendered:', title)
return <h1 style={style}>{title}</h1>
})
export default function App() {
const [count, setCount] = useState(0)
const normalStyle = {
backgroundColor: 'teal',
color: 'white',
}
const memoizedStyle = useMemo(() => {
return {
backgroundColor: 'red',
color: 'white',
}
}, [])
return (
<>
<button
onClick={() => {
setCount(count + 1)
}}
>
Increment {count}
</button>
<Heading style={memoizedStyle} title="Memoized" />
<Heading style={normalStyle} title="Normal" />
</>
)
}
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Returns a memoized value.
Pass a “create” function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.
Remember that the function passed to useMemo runs during rendering. Don’t do anything there that you wouldn’t normally do while rendering. For example, side effects belong in useEffect, not useMemo.
If no array is provided, a new value will be computed on every render.
You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.
//A poor performing function. The expensiveCalculation function runs on every render
import { useState } from "react";
import ReactDOM from "react-dom/client";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const calculation = expensiveCalculation(count);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = () => {
setTodos((t) => [...t, "New Todo"]);
};
return (
<div>
<div>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Add Todo</button>
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
<h2>Expensive Calculation</h2>
{calculation}
</div>
</div>
);
};
const expensiveCalculation = (num) => {
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {
num += 1;
}
return num;
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);