0

I have a small React project where the user can add notes to a Row, and then play MIDI audio of the notes that have been added (using react-abc / abcjs). The selected Notes should also animate in, using react-transition-group.

My problem is that only one of these features (MIDI / animation) will work at the same time, and which one works depends on a parent components key property. The two keys are

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
*/

I can understand why the animation would stop working - if the key updates with new data, and not just the index, the component will re-render, which means the animation cannot happen.

But I cannot understand why the MIDI would stop working properly when the key is just the index.

It took me quite a while to even figure out that the key was causing the MIDI to stop playing. I've tried moving the MIDI component to different locations with no results, and I'm pretty stumped.

I have created a (hopefully simple) working Sandbox of my issue with instructions to replicate: https://codesandbox.io/s/transition-group-x-abc-midi-bug-hunt-so-279pv?fontsize=14&hidenavigation=1&theme=dark

I have commented every main component with information, but the 2 most relevant components to my problem are:

Board.js: where the key can be changed to demonstrate the issue

CardRow.js: where the actual react-abc / Midi and react-transition-group components are located.

damon
  • 2,687
  • 8
  • 25
  • 35

1 Answers1

1

I like your example, nice work.

It was a big revelation when I understand how key works in React. Let me explain you what happens here.

Key tells react if a component representation in the dom is reused or not. If key remain the same it will be reused. If it changes it will be destroyed and remounted.

So when you use rowIndex as key. It remains the same and the animation works. But somehow the Midi is not refreshed. Midi has some issues, I do not know what.

When the key changes CardRow is remounted and it destrows the animation. Midi is also remounted and it works.

My solution is that I use rowIndex as key. And I added RowNotation as key to the Midi. Only Midi will be remounted. And both animation and midi works.

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

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

Peter Ambruzs
  • 7,763
  • 3
  • 30
  • 36
  • It works! Thank you for not just the solution, but an elaboration on how keys work. I didn't think about it before, but it now makes sense to me that by supplying a key to the `Midi` component, it would enable it to remount and update correctly when it previously wasn't. Given how obscure `react-abc` is, I wasn't optimistic that anyone would be willing to look into this, but you've come to the rescue. I'm so grateful you did. I really, really appreciate your help! :) – damon Feb 12 '20 at 15:01
  • 1
    My questions are usually quite complex also. But most of them get answered sooner or later. I'm glad I could helped. – Peter Ambruzs Feb 12 '20 at 15:47