key
is pretty much crucial for state perservation in React. As of React 0.13 it can't do the following things:
- Clone state
<Comp key={1} /><Comp key={1} />
- Preserve component state across different parents:
// first render
<div><Comp key={1} /></div>
// second render, state destroyed
<span><Comp key={1} /></span>
- More generally, teleport state to another subtree completely:
// render of myComp1
<Comp key={uuid} />
// next render, myComp2
<Comp key={uuid} />
The reason I want these is to unlock some insane tricks, e.g.
- Teleport a half-done animation to another place, i.e. animated transition across views (easily solvable otherwise).
- A generalized version of frosted glass effect.
- Other similar logic, e.g. drag and drop component where a stateful component is transported somewhere else.
But I dislike key for a few reasons, one being that it's basically a user-generated hash, and that's unreliable and doesn't scale: for example, that duplicate component trick is risky, as it's not clear whether we really wanted <Comp key={1} /><Comp key={1} />
or if we accidentally did a key collision.
The (only?) other used alternative I've seen for key is cursors. But I've repeatedly heard that while these solve the problem (?), they're a bit tedius to work with. Is this true? Please leave a comment if you have any experience regarding this. The solution doesn't need reactive updates, or easier state propagation, or any of the nice extras; it just needs to solve the above few cases.
Damn gists not notifying me of replies :)
@jimfb You may be right, I'm mainly approaching this in-terms of being feature complete with how you would previously manually manage your components if you didn't have React to do it for you. I find that you end up with the most basic ideas then which make for a good unopinionated starting point, you avoid any unnecessary assumptions and closing any doors (controlled components are great, but I still think uncontrolled components may play an important role). "Back then" you would simply hang on to a reference to your unparented component tree (as you say) and keep it somewhere handy so that it can be given a parent again when desired.
PS. I don't think "reusing nodes" should be reduced to the idea of only being considered a "perf optimization".