Reputation: 731
I always thought the only place that a unique key is needed is inside lists
and arrays
like map
, but today i was writing a loading screen for my component so a loading is shown to the user and after the load ends i do a setState and let the render know that its time to render the real view.
But i saw that the new component is not being rendered and the loading remains on the screen! after lots of testing i saw everything works as it should and finally i thought lets give it a key maybe something happens!! and it did !, the problem was solved, and i was confused as why on earth a key was needed there
So here is a sudo code of what i did and what happend :
render () {
//with no key, this doesn't render properly
const finalView = this.state.isLoading ?
<UIManager key={1} json= {myLoadingComponentJSON} />
:
<UIManager key={2} json={myFormJson} />;
return () {
finalView
}
}
I can defiantly see that the problem here is probably that i am using a component called UIManager
and i use a JSON
to know what kinda element this component should render, and probably both UIManagers had the same key? well i am not sure, but still i didn't think a key was needed here.
Upvotes: 3
Views: 81
Reputation: 12174
Which places and for what elements do we have to provide a unique key?
Only provide a key
for siblings where you expect the items to be re-ordered (think of list items).
If a child is unique (i.e doesn't have siblings), no need for a key
key
should be unique across siblings with the same ancestor.
So for the case of UIManager
, you can supply a name as key.
i.e
const finalView = this.state.isLoading ?
<UIManager key={'LoadingComp'} json= {myLoadingComponentJSON} />
:
<UIManager key={'Form'} json={myFormJson} />;
Why?
The real cause is how React does Reconciliation. Without the key
, React only sees json
attribute and check if it changed or not (might have performance problems with deeply nested JSON data - slow / dropped frames). If it sees any change in json
, it will destroy previous instance of UIManager
.
See Tradeoffs due to heuristics.
Summary:
With supplying a key
, it makes it easier for React to check the difference.
Upvotes: 4
Reputation: 3238
Reconciliation
React provides a declarative API so that you don’t have to worry about exactly what changes on every update. This makes writing applications a lot easier, but it might not be obvious how this is implemented within React. This article explains the choices we made in React’s “diffing” algorithm so that component updates are predictable while being fast enough for high-performance apps.
Because React relies on heuristics if the assumptions behind them are not met, performance will suffer.
The algorithm will not try to match the subtrees of different component types. If you see yourself alternating between two-component types with very similar output, you may want to make it the same type. In practice, we haven’t found this to be an issue.
Keys should be stable, predictable, and unique. Unstable keys (like those produced by Math.random()) will cause many component instances and DOM nodes to be unnecessarily recreated, which can cause performance degradation and lost state in child components.
In your case, you are rendering the same component UIManager
with different props so react can't identify which one to render that is the main reason behind
it's working after setting key
When you set key react identify them as a different component, though you could try the following approach
render () {
const finalView =
<UIManager json= { this.state.isLoading ? myLoadingComponentJSON : myFormJson} /> ;
return () {
finalView
}
}
Upvotes: 1