I've been having some issues today trying to maintain focus on an element as I re-render it. After some investigation I've found what appears to be a rendering issue in Preact... or I'm doing something incorrect (very possible).
I've created two examples, one in React .

and one in Preact.

You can see that as I click through the buttons only the ones that change render in React. If I click the highlighted one nothing renders as nothing changed.
When I do the same in Preact, even if the already active button, the parent and all children render each time.
I tried applying more keys but that didn't seem to help.
Seems like it might be a bug (need to look at this a bit more).
For the record though, there is actually no reason to use keys here at all. Keys are only useful when you have large lists of complex items that get reordered. In all other cases they actually hurt performance.
@developit thanks that's good to know
@mikestead Apologies for the terse reply, I was on my phone. One thing to note: the purple highlight in DevTools is actually indicating that a re-ordering happened, not a re-rendering _(I believe it differentiates by highlighting both the parent and the children at the same time, and only the element names)_. What's happening is all the keys are mismatched on every render, causing the elements to be reordered despite that being more work for the diff than simply adding or removing the selected class.
In looking at the pen, I've realized where the issue arose: in Preact, pure functional components like your <LinkButton /> are ephemeral (ie: they are not instantiated), which means the key prop you're passing into the component actually is just acting like a normal prop. On subsequent renders though, the key is then compared to the DOM element (the <li>), and since the key isn't being passed to that as a prop, it never matches. I'd call that a bug, since we would like keys to work for pure functional components in a similar manner to how they work for classful ones. That said, I'm actually working on a modification that will treat pure functional components as lightweight classful components, improving their performance - this will also have the effect of making keys work properly for them. I've tested this by modifying your Codepen's <LinkButton /> to be a classful component, and the result looks identical to the React version.
I don't mind keeping this issue open to track progress of key handling for pure functional components, but it's likely to get fixed as a result of that more fundamental change rather than a direct codepath to handle pure functional components with keys.
Cheers! 馃嵒
Great explanation thanks. Just removing the key in this scenario fixes the issue!
I agree it might be worth keeping this open in case anyone happens across it before your improvements go in.
Thanks again 馃憤
Update: support for keys on Pure Functional Components is fixed and will be released in 7.2 (or possible 8.0).
Fixed in 8.
Most helpful comment
Update: support for keys on Pure Functional Components is fixed and will be released in 7.2 (or possible 8.0).