I am reading the latest official react docs, https://react.dev/learn/preserving-and-resetting-state. There is one concept which i could not understand and hope someone could help.
The doc mentions React keeps state for as long as the same component is rendered at the same position.
Below one is a same place example and Counter component will share same state.
{isPlayerA ? (
<Counter person="Taylor" />
) : (
<Counter person="Sarah" />
)}
Below is an example of different places.. Does anyone knows why it behave like that? thank you.
2
Answers
This is sort of a guess so take with a pinch of salt but…
When JSX gets compiled each of the
{ ... }
parts (along with any elements) gets turned into an entry in a childrens array that gets passed to something equivalent to React.createElement(). Each of these entries can resolve to null / false, so won’t appear in output but would still take up a slot in the childrens array.For example:
might become the equivalent of something like:
where
'Wibble'
,dave && React.createElement("bob", {})
,!dave && React.createElement("fred", {})
will become the items in the children array used by React to track the child elements. In this casedave && React.createElement("bob", {})
and!dave && React.createElement("fred", {})
will have separate indexes in the array and therefore separate positions in the output even thoughdave && React.createElement("bob", {})
resolves tonull
and therefore doesn’t output anything.In the first example you gave
would resolve to one entry in the children array and so each branch of the ternary operator would have the same position in the childrens array.
Example JSX to JS output with Babel.
Also guessing a bit here, but this behavior seems like a result of the react internal algorithm that creates the react-"UI tree" from JSX markup.
See react docs
Now, at least to me, it’s not always clear how react proceeds to generate the UI tree from JSX in detail, but:
See react docs
This sounds like this "hole" is present in the UI-tree, meaning that
&&
creates an own position for the component if the condition is true and also removes it from there if the condition is false.On the other hand, when react reads the ternary operator (
? :
) it seems to try to switch out the components at the same tree position. This would make sense with this "hole" argumentation, since in this case, there is nofalse
orundefined
that react could consider as a "hole".Correct me if I’m wrong, but this is my understanding so far.