reactjsvirtual-dom

React: How to detect the same components


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?


Solution

  • 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 /> or false 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 the hiddenFlag is toggled.

    In the case of

    hiddenFlag ? (
      <div>
        <MyComponent/>
      </div>
    ) : (
      <div>
        <MyComponent />
        <MyComponent/>
      </div>
    );
    

    The best react can do is assume the order of elements is the same so the first MyComponent retains the state.