React.memo-なぜ等値関数が呼び出されないのですか?


8

小道具を介して受信した配列に基づいて子のコレクションをレンダリングする親コンポーネントがあります。

import React from 'react';
import PropTypes from 'prop-types';
import shortid from 'shortid';
import { Content } from 'components-lib';
import Child from '../Child';

const Parent = props => {
  const { items } = props;

  return (
    <Content layout='vflex' padding='s'>
      {items.map(parameter => (
        <Child parameter={parameter} key={shortid.generate()} />
      ))}
    </Content>
  );
};

Parent.propTypes = {
  items: PropTypes.array
};

export default Parent;

新しいものitemが追加されるたびに、すべての子が再レンダリングされ、それを回避しようとしています。他の子が再レンダリングされたくないので、最後に追加された子をレンダリングしたいだけです。

だから、私は子供でReact.memoを試してみましたが、おそらくcodeプロパティか何かで比較します。問題は、等価関数が呼び出されないことです。

import React from 'react';
import PropTypes from 'prop-types';
import { Content } from 'components-lib';

const areEqual = (prevProps, nextProps) => {
  console.log('passed here') // THIS IS NEVER LOGGED!!
}

const Child = props => {
  const { parameter } = props;
  return <Content>{parameter.code}</Content>;
};

Child.propTypes = {
  parameter: PropTypes.object
};

export default React.memo(Child, areEqual);

何かアイデアはありますか?


1
小道具が変更されるまで何も記録しません。親の小道具を微調整してみてください。
優しいユーザー、

import `import Child from '../Child'`にエラーがあります。それが原因かどうかは不明です。
Afia

1
子コンポーネントの不要な再レンダリングを防止する場合は、それぞれに一意のキーを与える必要があります。Reactにはキーを扱う非常にデリケートな方法があり、コンポーネントのキーが変更された場合、Reactはそれを完全に再レンダリングします。毎回新しいキーを生成すると、親のプロップが変更されるたびにReactがすべてを再レンダリングします。
コンスタンティン

@konstantinあなたは天才です!! 鍵生成を外してみたら、魅力的でした!! :D等価fnが呼び出され、比較を行うことができました。ありがとう!! これを回答として追加して、正しいものとして投票できるようにできますか?
Joana Deluca Kleis

私が助けてくれてうれしい:)、今すぐ追加します
Konstantin

回答:


2

つまり、この動作の理由は、Reactの動作方法にあります。

Reactは各コンポーネントに一意のキーを期待しているので、追跡してどれがどれかを知ることができます。shortid.generate()キーの新しい値を使用することにより、コンポーネントへの参照が変更され、Reactはそれを完全に新しいコンポーネントであると見なし、レンダリングが必要になります。

あなたの場合、親のプロップが変更されると、前のレンダーと比較してすべての子のキーが異なるため、Reactはすべての子を再レンダリングします。

このトピックに対するこの素晴らしい答えを参照してください

お役に立てれば!


0

私はあなたのライブラリの残りを知りませんが、私はいくつかの変更とあなたのコードを行いました、そして(ほとんど)動作しているようです。だから、多分、それはあなたが原因を絞り込むのを助けることができます。

https://codesandbox.io/s/cocky-sun-rid8o


お時間をいただき、コードサンドボックスを作成していただきありがとうございます。それは有り難いです!私の場合は少し異なります。ボタンをクリックすると明示的にプロパティが変更され、fnがトリガーされます。私の場合、親の配列に新しい項目を追加し、毎回新しい子を作成し、fnがトリガーされることを期待しています。問題がランダムに生成していた鍵であることがわかりました。
Joana Deluca Kleis
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.