機能をリクエストしバグを報告しますか?
バグ
現在の動作は何ですか?
key
が各アイテム要素の一意のプロパティとして設定されているアイテムのリストをレンダリングするときに、アイテムの順序が以前のレンダリングから変更されると、インデックスが変更されたアイテム要素が再レンダリングされるのではなく再レンダリングされます(新しいインスタンスが作成されます)。 -既存のインスタンスを使用(キーを介してマッピング)。
たとえばhttps://codesandbox.io/s/r5p48kzop
各ボックスにid
、 top
、 left
color
小道具があるリストboxes
をレンダリングします。 750ms
ごとに、 boxes
配列内のすべての要素の( top
、 left
)値を更新します。
要素の順序が変更されていない場合は更新中に、すべてのボックスが新しい位置にアニメーション化されます。 ただし、ボックスをシャッフルする行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.2
& 16.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をサポートしていないため、そのブラウザーでテストできませんでした)。
ちょっと@ philipp-spiess問題と回避策の例を明確にしてくれてありがとう。
こんにちは、@ philipp-spiess
リストの並べ替えでも同じ問題があります😔
残念ながら、上記のCodesandboxの例はもう機能していません(
次に例を示します。
https://jsfiddle.net/9odLvbrx/
簡単なCSSトランジションでクリック時にアイテムを並べ替えます。
問題は、トランジションが選択したアイテムにのみ表示され、残りのアイテムが省略されることです。
この問題を回避する方法は知っていますが(コードにコメントされています)、アイテムの数量が変更されないリストでのみ正常に機能します。 したがって、アイテムを追加または削除したい場合、内容は非常に複雑になります。 私の例でそれを実現するために、リフロー過負荷ソリューションをどのように使用できますか?
前もって感謝します! 😊
最も参考になるコメント
ねえ@ dhruvparmar372!
これはDOMの制限のようです。 これを実証するために、2つのDOMノードの順序を変更し、クラスを適用して遷移をトリガーするこのJSFiddleを作成し
順序の変更とアニメーションプロパティの更新の間のリフローをトリガーすることで、この問題を回避できることがわかりました。
<Box />
をクラスコンポーネントに変更し、コンストラクターで一意のIDを作成することにより、Reactによってコンポーネントが再作成されたときに表示されるようにCodeSandboxにコードを少し追加しました。 ご覧のとおり、IDは一貫性を保ちます: //codesandbox.io/s/jn42wvl343それに加えて、更新を2つの
setState
分割することで、リフローの回避策を例に適用しました。 最初のものは順序を変更し、次にリフローをトリガーし、その後位置を変更します。 これは、Chrome、Firefox、Safari、およびEdgeで正常に機能するようです(CodeSandboxはIE11をサポートしていないため、そのブラウザーでテストできませんでした)。