React.memoは、Reactの純粋なコンポーネントの機能を提供しますが、クラスベースのコンポーネントではなく機能ベースのコンポーネント用です。
memoizationは、高価な関数呼び出しの結果をキャッシュし、引数が同じ場合にキャッシュされたバージョンを返すことを意味するコンピュータサイエンスの専門用語です。
Reactの用語で:
渡されるpropsが同じである場合、MyNewComponentが再レンダリングされることは望ましくありません。
簡単なカウンターの例
React.memoがどのように機能するかを頭に入れておくために、Codesandboxで次の例を作成しました。
ボタンがクリックされた回数をカウントするシンプルなアプリです。 下のスクリーンショットから、ページの上部にバナーが表示されていることがわかります。
BannerがさまざまなタイプのUIコンポーネントであると想像してください。この場合、infoタイプのバナーを使用して、Bannerを次のように作成します。
<Banner type="info" />
CounterComponentは次のようになります。
class CounterComponent extends Component {
state = { buttonPressedCount: 0 };
render() {
const { buttonPressedCount } = this.state;
return (
<div className="new-component">
<h4>Button Pressed Count: {buttonPressedCount}</h4>
<button
onClick={() =>
this.setState({ buttonPressedCount: buttonPressedCount + 1 })
}
>
Increase Count
</button>
<Banner type="info" />
</div>
);
}
}
また、Bannerコンポーネントは次のようになります。
const Banner = props => {
const { type } = props;
if (type === "info") {
return <div className="info-banner">I am an info banner</div>;
}
};
CounterComponentでは、ボタンをクリックするたびにbuttonPressedCount変数を増やして、期待どおりの再レンダリングを行います。 これに伴う問題は、渡されるpropsが変更されていなくても、Bannerコンポーネントも再レンダリングされることです。
これを回避するために、propsが変更されていない場合に再レンダリングを停止するという点で、PureComponentのように機能するmemoを使用します。 更新されたコードは次のようになります。
const Banner = memo(props => {
const { type } = props;
if (type === "info") {
return <div className="info-banner">I am an info banner</div>;
}
});
これで、Bannerコンポーネントは、propsが変更された場合にのみ再レンダリングされます。
これがReactメモの基本的な考え方です。
は同じ
では、もう少し進んで、カスタムの平等について話しましょう。 デフォルトでは、memoは、小道具と小道具のオブジェクトのshallow比較のみを行います。 2番目の引数を渡して、カスタムの同等性チェックを示すことができます。
React.memo(Component, [areEqual(prevProps, nextProps)]);
これはshouldComponentUpdateに似ていますが、逆です。 shouldComponentUpdateでtrueを返すと、別のレンダリングが発生しますが、areEqualはその逆です。
オブジェクトであるprop人を受け入れるPersonコンポーネントがあると想像してください。nameが同じであるかどうかを確認できます。
const areEqual = (prevProps, nextProps) => {
return (prevProps.name === nextProps.name)
};
React.memo(Person, areEqual);
結論
これはReactへの本当に素晴らしい追加であり、不必要な再レンダリングを心配することなく機能コンポーネントを使用することができます。 いつものように、この投稿で何か良いことを学んだことを願っています!