React: 一意の「キー」を持つリストアイテムは、アイテムの順序が変更されると再レンダリングされます。

作成日 2018年07月15日  ·  3コメント  ·  ソース: facebook/react

機能をリクエストしバグを報告しますか?
バグ

現在の動作は何ですか?
keyが各アイテム要素の一意のプロパティとして設定されているアイテムのリストをレンダリングするときに、アイテムの順序が以前のレンダリングから変更されると、インデックスが変更されたアイテム要素が再レンダリングされるのではなく再レンダリングされます(新しいインスタンスが作成されます)。 -既存のインスタンスを使用(キーを介してマッピング)。

たとえばhttps://codesandbox.io/s/r5p48kzop
各ボックスにidtopleft color小道具があるリストboxesをレンダリングします。 750msごとに、 boxes配列内のすべての要素の( topleft )値を更新します。

要素の順序が変更されていない場合は更新中に、すべてのボックスが新しい位置にアニメーション化されます。 ただし、ボックスをシャッフルする行31のコメント

この動作はサンドボックスで確認できます。 _shuffleオンにすると、ボックスが新しい位置にジャンプすることがありますが、 _shuffleオフにすると、常にアニメーション化されます。

現在の動作がバグである場合は、再現する手順と、可能であれば問題の最小限のデモを提供してください。 以下のJSFiddle(https://jsfiddle.net/Luktwrdm/)またはCodeSandbox(https://codesandbox.io/s/new)の例へのリンクを貼り付けます。
https://codesandbox.io/s/r5p48kzop

期待される動作は何ですか?
boxesの順序に関係なく、すべてのボックス要素には一意のkeyプロパティが設定されているため、すべてのボックス要素が新しい位置にアニメーション化されます。

Reactのどのバージョン、およびどのブラウザ/ OSがこの問題の影響を受けますか?
React 16.3.216.4.1 、Chrome、MacOS。

最も参考になるコメント

ねえ@ dhruvparmar372!

これはDOMの制限のようです。 これを実証するために、2つのDOMノードの順序を変更し、クラスを適用して遷移をトリガーするこのJSFiddleを作成し

順序の変更とアニメーションプロパティの更新の間のリフローをトリガーすることで、この問題を回避できることがわかりました。

<Box />をクラスコンポーネントに変更し、コンストラクターで一意のIDを作成することにより、Reactによってコンポーネントが再作成されたときに表示されるようにCodeSandboxにコードを少し追加しました。 ご覧のとおり、IDは一貫性を保ちます//codesandbox.io/s/jn42wvl343

それに加えて、更新を2つのsetState分割することで、リフローの回避策を例に適用しました。 最初のものは順序を変更し、次にリフローをトリガーし、その後位置を変更します。 これは、Chrome、Firefox、Safari、およびEdgeで正常に機能するようです(CodeSandboxはIE11をサポートしていないため、そのブラウザーでテストできませんでした)。

全てのコメント3件

ねえ@ dhruvparmar372!

これはDOMの制限のようです。 これを実証するために、2つのDOMノードの順序を変更し、クラスを適用して遷移をトリガーするこのJSFiddleを作成し

順序の変更とアニメーションプロパティの更新の間のリフローをトリガーすることで、この問題を回避できることがわかりました。

<Box />をクラスコンポーネントに変更し、コンストラクターで一意のIDを作成することにより、Reactによってコンポーネントが再作成されたときに表示されるようにCodeSandboxにコードを少し追加しました。 ご覧のとおり、IDは一貫性を保ちます//codesandbox.io/s/jn42wvl343

それに加えて、更新を2つのsetState分割することで、リフローの回避策を例に適用しました。 最初のものは順序を変更し、次にリフローをトリガーし、その後位置を変更します。 これは、Chrome、Firefox、Safari、およびEdgeで正常に機能するようです(CodeSandboxはIE11をサポートしていないため、そのブラウザーでテストできませんでした)。

ちょっと@ philipp-spiess問題と回避策の例を明確にしてくれてありがとう。

こんにちは、@ philipp-spiess

リストの並べ替えでも同じ問題があります😔
残念ながら、上記のCodesandboxの例はもう機能していません(

次に例を示します。
https://jsfiddle.net/9odLvbrx/
簡単なCSSトランジションでクリック時にアイテムを並べ替えます。
問題は、トランジションが選択したアイテムにのみ表示され、残りのアイテムが省略されることです。

この問題を回避する方法は知っていますが(コードにコメントされています)、アイテムの数量が変更されないリストでのみ正常に機能します。 したがって、アイテムを追加または削除したい場合、内容は非常に複雑になります。 私の例でそれを実現するために、リフロー過負荷ソリューションをどのように使用できますか?

前もって感謝します! 😊

このページは役に立ちましたか?
0 / 5 - 0 評価