import { memo, useMemo, useState } from 'react';
import './App.css';
type Person = {
firstName: string;
lastName: string;
};
type WithInitial = Person & {
initials: string;
};
const initialPeople: Person[] = [
{ firstName: 'John', lastName: 'Lennon' },
{ firstName: 'Paul', lastName: 'McCartney' },
{ firstName: 'George', lastName: 'Harrison' },
{ firstName: 'Ringo', lastName: 'Starr' },
];
function App() {
const [theme, setTheme] = useState('light');
const [people, setPeople] = useState(initialPeople);
const [counter, setCounter] = useState(0);
return (
<div>
<button onClick={() => setCounter((prev) => prev + 1)}>
Increase {counter}
</button>
<button onClick={toggleTheme}>Toggle {theme}</button>
<button onClick={addRandomPerson}>Add Random Person</button>
<ListComponentNoMemo {...{ theme, people }} />
<ListComponentWithMemo {...{ theme, people }} />
<MemoListComponentWithMemo {...{ theme, people }} />
</div>
);
function toggleTheme() {
setTheme((prev) => (prev === 'light' ? 'dark' : 'light'));
}
function addRandomPerson() {
setPeople((prev) => [
...prev,
{
firstName: Math.ceil(Math.random() * 100).toString(),
lastName: Math.ceil(Math.random() * 100).toString(),
},
]);
}
}
function ListComponentNoMemo({
theme,
people,
}: {
theme: string;
people: Person[];
}) {
console.log('ListComponentNoMemo');
const withInitials = processInitials('noMemo', people);
return (
<>
<p>Theme is {theme}</p>
<ul>
{withInitials.map((e, index) => (
<li key={index}>
{e.firstName} {e.lastName} {e.initials}
</li>
))}
</ul>
</>
);
}
function ListComponentWithMemo({
theme,
people,
}: {
theme: string;
people: Person[];
}) {
console.log('ListComponenWithMemo');
const withInitials = useMemo(
() => processInitials('withMemo', people),
[people]
);
return (
<>
<p>Theme is {theme}</p>
<ul>
{withInitials.map((e, index) => (
<li key={index}>
{e.firstName} {e.lastName} {e.initials}
</li>
))}
</ul>
</>
);
}
const MemoListComponentWithMemo = memo(function ({
theme,
people,
}: {
theme: string;
people: Person[];
}) {
console.log('MemoListComponenWithMemo');
const withInitials = useMemo(
() => processInitials('memoWithMemo', people),
[people]
);
return (
<>
<p>Theme is {theme}</p>
<ul>
{withInitials.map((e, index) => (
<li key={index}>
{e.firstName} {e.lastName} {e.initials}
</li>
))}
</ul>
</>
);
});
function processInitials(calledFrom: string, people: Person[]): WithInitial[] {
console.log({ calledFrom });
return people.map((e) => ({
firstName: e.firstName,
lastName: e.lastName,
initials: toInitials(e),
}));
function toInitials(p: Person) {
console.log('emphasized expensiveness');
return p.firstName[0] + p.lastName[0];
}
}
export default App;
Live: https://stackblitz.com/edit/vitejs-vite-drznsqwc?file=src%2FApp.tsx
Thursday, June 26, 2025
React: Memoized unchanged properties
This demonstrates that it is expensive to re-render/re-process a variable when its value is not changing
Labels:
Optimization,
React
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment