react-transition-group 和 react-abc (abcjs) Midi 不会同时工作(取决于父组件的 Key)?

react-transition-group and react-abc (abcjs) Midi will not work at the same time (depends on Key of parent component)?

我有一个小型 React 项目,用户可以在其中向行添加音符,然后播放已添加音符的 MIDI 音频(使用 react-abc / abcjs). The selected Notes should also animate in, using react-transition-group.

我的问题是这些功能中只有一个(MIDI/动画)可以同时工作,哪个工作取决于父组件 key 属性。两个键是

key={rowIndex + rowNotation}
key={rowIndex}
// where `rowNotation` is the updated data of what the MIDI should play when every new card is added

/* If `key` = `rowIndex + rowNotation`, MIDI will play when green button is pushed, but
 react-transition-group will not perform an animation when adding / removing notes

 If `key` = `rowIndex`, react-transition-group will perform enter / exit
 animations, but react-abc MIDI will NOT play
*/

我能理解为什么动画会停止工作 - 如果键用新数据更新,而不仅仅是索引,组件将重新渲染,这意味着动画不会发生。

但是我无法理解为什么当键只是索引时 MIDI 会停止正常工作。

我花了很长时间才弄清楚是这个键导致 MIDI 停止播放。我试过将 MIDI 组件移动到不同的位置但没有结果,我很困惑。

我已经为我的问题创建了一个(希望是简单的)工作沙箱,并附有复制说明:https://codesandbox.io/s/transition-group-x-abc-midi-bug-hunt-so-279pv?fontsize=14&hidenavigation=1&theme=dark

我已经用信息评论了每个主要组成部分,但与我的问题最相关的两个组成部分是:

Board.js:可以更改密钥以演示问题

CardRow.js:实际 react-abc / Midireact-transition-group 组件所在的位置。

我喜欢你的例子,做得很好。

当我了解 key 在 React 中的工作原理时,这是一个很大的启示。让我来解释一下这里发生了什么。

Key 告诉 React dom 中的组件表示是否被重用。如果密钥保持不变,它将被重复使用。如果它发生变化,它将被销毁并重新安装。

因此,当您使用 rowIndex 作为键时。它保持不变并且动画有效。但不知何故,Midi 并没有刷新。 midi有点问题,不知道是什么。

当键改变时,CardRow 被重新安装并取消动画。 Midi也重新挂载了,可以用了。

我的解决方案是使用 rowIndex 作为键。我将 RowNotation 添加为 Midi 的键。只有 Midi 会被重新挂载。动画和 midi 都可以。

<Midi
  key={rowNotation}
  midiParams={{
    qpm: 80
  }}
  notation={rowNotation}
/>

https://codesandbox.io/s/transition-group-x-abc-midi-bug-hunt-so-rwjkk