React.memo、useMemo、useCallback がいつ本当にアプリを速くし、いつ意味もなく複雑にするのかを学びます。
このレッスンを Kodokon で開くコンポーネントが再レンダーされると、その子はすべてデフォルトで再レンダーされます。props が変わったかどうかに関係なくです。それは悲劇ではありません。レンダーは出力が変わったときにのみ DOM に触れます。メモ化が意味を持つのは、頻繁なレンダーと高コストなサブツリーが出会うときです。3 つの道具、3 つの標的があります。React.memo は props が浅く等しければコンポーネントのレンダーをスキップし、useMemo は計算された 値 をキャッシュし、useCallback は 関数 をキャッシュします。3 つとも参照の等価性に依存しています。
import { memo } from "react";
const Row = memo(function Row({ item, onSelect }) {
return (
<li onClick={() => onSelect(item.id)}>{item.label}</li>
);
});鎖の強さはもっとも弱い環と同じです。1 つの prop でもレンダーごとに新しい参照を受け取れば - インラインのアロー関数、オブジェクトや配列のリテラル - memo の比較は失敗し、コンポーネントはいずれにせよ再レンダーされます。useCallback は関数の参照を安定させ、比較が成功するようにします。
import { useCallback } from "react";
function List({ items }) {
const handleSelect = useCallback((id) => {
console.log("selected:", id);
}, []);
return (
<ul>
{items.map((item) => (
<Row
key={item.id}
item={item}
onSelect={handleSelect}
/>
))}
</ul>
);
}useMemo には正当な用途が 2 つあります。本当に高コストな計算 を避けること(数千件の項目のソートや集計)、そしてメモ化された子が消費する、あるいはエフェクトの依存配列に並ぶ 参照を安定させる ことです。ささいな計算では、キャッシュのほうが節約より高くつきます。依存関係の比較、保持されるメモリ、重くなる読解です。
import { useMemo } from "react";
function Stats({ orders }) {
const total = useMemo(() => {
return orders.reduce(
(sum, order) => sum + order.amount,
0
);
}, [orders]);
return <p>Total: {total} €</p>;
}