When scrolling vertically in a TableListBox, refreshComponentForCell() for the new rows is being called with the existingComponentToUpdate instance of the old rows instead of nullptr, resulting in showing a copy of the old rows instead of the new ones.
It’s a “feature”. You’re supposed to reuse this existing cell and update its data (label, colour, whatever). Juce manages the cells and their memory for you but in exchange you have to handle the two cases: new cell, or cell reuse.
Juce made me such a bum I didn’t even think about this option, thanks.