Memoized list
- React course
- Intermediate
- Lesson 36/80
- 5 min
Stop needless renders with a memoized list item.
Memo'd list
The final lesson adds the MemoRow component. It's wrapped with React.memo; thanks to stable props, only the relevant row renders. This is where the three lessons merge.
StatsApp: numbers + StatsPanel (useMemo). StatsRow: handleClick (useCallback). MemoRow: row component wrapped with React.memo. When the three merge, you get full performance optimization.
This structure makes a serious difference in big lists (1000+ rows). Profiling tools show that needless renders drop.
Practice Write MemoRow
Complete the skeleton. Write a Row component; take ({ '{ id, onClick }' }) and return <li onClick={ '{ () => onClick(id) }' }>{ '{ id }' }</li>. Wrap with const MemoRow = memo(Row);. Export MemoRow.
Starter code
import { memo } from "react";
// Write Row and MemoRow hereSample solution
import { memo } from "react";
function Row({ id, onClick }) {
return <li onClick={() => onClick(id)}>{id}</li>;
}
const MemoRow = memo(Row);
export default MemoRow;Combine all pieces
At the end of three lessons, StatsApp, StatsPanel and MemoRow combine into a full optimization chain. Data is computed with useMemo, row click is stabilized with useCallback, and the row component is wrapped with React.memo.
This way, when one row changes in a 1000-row list, other rows are not re-rendered. You can see the difference in the React Profiler: render count drops significantly.
In the last step you will combine these three pieces into a single App component.
Practice Combine with App
Complete the skeleton below. Write an App component; use useState([1, 2, 3]) for ids, useCallback for handleClick (takes id, calls console.log(id)), and inside a ul, map ids to render MemoRow for each id. Export App.
Starter code
import { useState, useCallback, memo } from "react";
function Row({ id, onClick }) {
return <li onClick={() => onClick(id)}>{id}</li>;
}
const MemoRow = memo(Row);
// Write the App component hereSample solution
import { useState, useCallback, memo } from "react";
function Row({ id, onClick }) {
return <li onClick={() => onClick(id)}>{id}</li>;
}
const MemoRow = memo(Row);
function App() {
const [ids] = useState([1, 2, 3]);
const handleClick = useCallback((id) => console.log(id), []);
return (
<ul>
{ids.map((id) => (
<MemoRow key={id} id={id} onClick={handleClick} />
))}
</ul>
);
}
export default App;Combine all pieces
At the end of three lessons, StatsApp, StatsPanel and MemoRow combine into a full optimization chain. Data is computed with useMemo, row click is stabilized with useCallback, and the row component is wrapped with React.memo.
This way, when one row changes in a 1000-row list, other rows are not re-rendered. You can see the difference in the React Profiler: render count drops significantly.
In the last step you will combine these three pieces into a single App component.
Practice Combine with App
Complete the skeleton below. Write an App component; use useState([1, 2, 3]) for ids, useCallback for handleClick (takes id, calls console.log(id)), and inside a ul, map ids to render MemoRow for each id. Export App.
Starter code
import { useState, useCallback, memo } from "react";
function Row({ id, onClick }) {
return <li onClick={() => onClick(id)}>{id}</li>;
}
const MemoRow = memo(Row);
// Write the App component hereSample solution
import { useState, useCallback, memo } from "react";
function Row({ id, onClick }) {
return <li onClick={() => onClick(id)}>{id}</li>;
}
const MemoRow = memo(Row);
function App() {
const [ids] = useState([1, 2, 3]);
const handleClick = useCallback((id) => console.log(id), []);
return (
<ul>
{ids.map((id) => (
<MemoRow key={id} id={id} onClick={handleClick} />
))}
</ul>
);
}
export default App;Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What wraps MemoRow?
- React.memo Correct answer
- useMemo
- useState
- useEffect
Explanation: Wrapped with React.memo.
2 Match the performance merge
| Term | Meaning |
|---|---|
StatsPanel |
useMemo |
StatsRow |
useCallback |
MemoRow |
memo |
merge |
full opt |