From 8a9efff83df3b7bcfddd44930c05a96cebc3b1b4 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 22 Sep 2022 15:13:55 +0100 Subject: [PATCH] [Beta] Tweak loop guidance --- beta/src/content/apis/react/useCallback.md | 24 ++++++++++++++++++++-- beta/src/content/apis/react/useMemo.md | 19 ++++++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/beta/src/content/apis/react/useCallback.md b/beta/src/content/apis/react/useCallback.md index 4b6eecbf8..538503356 100644 --- a/beta/src/content/apis/react/useCallback.md +++ b/beta/src/content/apis/react/useCallback.md @@ -856,7 +856,7 @@ When you find which dependency is breaking memoization, either find a way to rem ### I need to call `useCallback` for each list item in a loop, but it's not allowed {/*i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed*/} -You can't call `useCallback` in a loop: +Suppose the `Chart` component is wrapped in [`memo`](/api/react/memo). You want to skip re-rendering every `Chart` in the list when the `ReportList` component re-renders. However, you can't call `useCallback` in a loop: ```js {5-14} function ReportList({ items }) { @@ -879,7 +879,7 @@ function ReportList({ items }) { } ``` -Instead, extract a component for each item and memoize data for individual items: +Instead, extract a component for an individual item, and put `useCallback` there: ```js {5,12-21} function ReportList({ items }) { @@ -905,3 +905,23 @@ function Report({ item }) { ); } ``` + +Alternatively, you could remove `useCallback` in the last snippet and instead wrap `Report` itself in [`memo`.](/api/react/memo) If the `item` prop does not change, `Report` will skip re-rendering, so `Chart` will skip re-rendering too: + +```js {5,6-8,15} +function ReportList({ items }) { + // ... +} + +const Report = memo(function Report({ item }) { + function handleClick() { + sendReport(item) + } + + return ( +
+ +
+ ); +}); +``` \ No newline at end of file diff --git a/beta/src/content/apis/react/useMemo.md b/beta/src/content/apis/react/useMemo.md index 91d485845..0416be025 100644 --- a/beta/src/content/apis/react/useMemo.md +++ b/beta/src/content/apis/react/useMemo.md @@ -1274,7 +1274,7 @@ When you find which dependency is breaking memoization, either find a way to rem ### I need to call `useMemo` for each list item in a loop, but it's not allowed {/*i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed*/} -You can't call `useMemo` in a loop: +Suppose the `Chart` component is wrapped in [`memo`](/api/react/memo). You want to skip re-rendering every `Chart` in the list when the `ReportList` component re-renders. However, you can't call `useMemo` in a loop: ```js {5-11} function ReportList({ items }) { @@ -1317,3 +1317,20 @@ function Report({ item }) { ); } ``` + +Alternatively, you could remove `useMemo` and instead wrap `Report` itself in [`memo`.](/api/react/memo) If the `item` prop does not change, `Report` will skip re-rendering, so `Chart` will skip re-rendering too: + +```js {5,6,12} +function ReportList({ items }) { + // ... +} + +const Report = memo(function Report({ item }) { + const data = calculateReport(item); + return ( +
+ +
+ ); +}); +``` \ No newline at end of file