当用动态键包裹在 div 中时,React Collapse 过渡不会动画

React Collapse transition doesn't animate when wrapped in a div with a dynamic key

这真的很奇怪。我花了很多时间才弄清楚如何 解决这个问题。但即使修复了它,我也不知道为什么它在一种配置中损坏,但在另一种配置中却没有。

最好的解释方法是使用 StackBlitz 实例:https://stackblitz.com/edit/react-collapse-transition-breaks-with-dynamic-key

实例详细说明了确切的问题,但这里是概要:

为什么dynamic-key方法会破坏动画?

TLDR:在 React 中不要 dynamically-generate globally-unique 数组元素的键。

好的,经过多次谷歌搜索,我想我终于明白是怎么回事了。

当您在 React 中向数组添加项目时,如果您没有向数组中的每个元素添加唯一的 "key",则会引发警告。只要您使用 something unique 作为每个元素的 "key" 值,警告就会消失,并且在大多数情况下,React 似乎可以很好地管理数组元素。

当我开始 React 开发时(几年前),我想,“我可以通过使用随机 GUID-generating 函数向我的所有数组元素添加唯一键来轻松解决这个问题。所以我会经常使用如下代码:

let newArray = [];
someMasterArrayOfObjects.forEach(object => {
   if (someConditionIsMet) {
      // SEE HOW CLEVER I THOUGHT I WAS??  USING A RANDOMLY-GENERATED GUID QUIETS THE 
      // UNIQUE-KEY WARNINGS THAT ARE THROWN BY REACT
      newArray.push(
         <div key={createRandomGuid()}>
            {object.title}
         </div>
      );
   }
});

但是我错过了 ReactJS 文档中的一个关键词(强调,我的):

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a STABLE identity:

他们在文档中多次使用 "stable" 这个词,但我并没有真正理解它。像大多数开发人员一样,我首先关心的是删除数组元素缺少唯一键时抛出的警告。使用 randomly-generated GUID 解决了这个问题。

但是 React 使用这些键来确定在状态更改期间应该 re-rendered 什么。如果你每次在数组中构建元素时 randomly-generate 一个新的 globally-unique 键,那么 React 将假设所有这些元素都需要在你每次设置状态时从头开始完全重建。

至少,这是低效的。您可能不会注意到小 arrays/apps 中的任何性能影响,但没有理由人为地 force a re-rendering of every数组元素 一次出于任何原因设置该状态。您可能不会注意到您的应用程序中有任何视觉问题,但这是一种糟糕的做法。

在最坏的情况下,它实际上会破坏您的某些功能。在我的例子中,它打破了 过渡动画,因为渲染引擎无法比较一个状态变化和下一个状态变化之间增加的 "height" 值 - 因为每次尝试改变那个高度时,我都在分配一个"key" 值的全新 globally-unique 标识符,React 将其视为一个全新的、完全不同的组件。

一旦我终于弄明白要做什么 Google,我还发现了这个很棒的 JSFiddle:

http://jsfiddle.net/frosas/S4Dju/

请注意,他的示例中输入的中间行标题为 "Unique random keys"。当您手动更改其中一个 唯一随机键 的值时,然后单击 "Add item",它会破坏您更改的结果,因为它 re-renders 输入元素作为 brand-new 元素,与其先前的状态无关。