First of all, sorry for my poor English! (translated by DeepL)
MyComponent has some ‘state’ like a counter and displays it.
In pattern A, when the hiddenFlag is switched, ‘state’ of the first MyComponent is kept.
In pattern B, when the hiddenFlag is switched, ‘state’ of the second MyComponent is kept.
In both cases, the number of MyComponent displayed by hiddenFlag is the same.
How does React detect the same components?
Pattern A:
return hiddenFlag ? (
<div>
<MyComponent />
</div>
) : (
<div>
<MyComponent />
<MyComponent />
</div>
);
Pattern B:
return (
<div>
{!hiddenFlag && <MyComponent />}
<MyComponent />
</div>
);
I know that React has two phases "the rendering phase" and "the committing phase" when the state of a component changes. The former phase creates a virtual DOM and the latter rewrites the changed location compared to the current DOM.
Does this mean that when the if branch is calculated in the rendering phase of pattern A, it also determines that the first MyComponent is the same one?
2
Answers
If you are looking to persist a specific component, you can do so with the
key
prop. In the example below, I have created both of your scenarios, and provided keys to the counter elements. By doing so, in scenario A, I am able to tell react that the 2nd Counter is the one I want to persist.In react the
key
prop is a reserved prop that every component can have. It allows react to track & identify a specific component on the page. It must be used with arrays so that react knows which component of the array is being updated. You should avoid using the array index as the key whenever possible.Honestly, I’m a bit surprised that scenario A persists a counter when no
key
prop is provided. Up until today I would have expected react to treat scenario A as one or two new components.To my knowledge (I may be mistaken) when the
key
property is not specified – which is what you should do when the order of components can change, see Scott Z’s answer – React assumes the order of elements in the list of children will be constant each time.The statement
{!hiddenFlag && <MyComponent />}
will either give<MyComponent />
orfalse
depending on the flag, in either case it is seen as the "first" child of the div so the second element that is always the same retains state when thehiddenFlag
is toggled.In the case of
The best react can do is assume the order of elements is the same so the first
MyComponent
retains the state.