1

I've been trying to understand react reconciliation and am getting really confused by some of the details of how the diffing algorithm works. So far, I understand that whenever an update is made, we create a new react element tree and compare it with our previous react element tree. The diffing algorithm manages finding the difference between the new and old react element trees. The 2 assumptions of the algo. are that elements of the same level and type don't need to be unmounted and re-mounted and that keys provide a way of identifying child elements not by index.

The part that confuses me is how comparisons are made between 2 react instances. For example, when comparing <Comp1/> in the old react element tree and <Comp2/> in the new react element tree (assume that <Comp2> replaced <Comp1> in the creation of the new tree), does the diffing algorithm simply compare both react elements' "type" attributes? So if both have the same "type", then the diffing algorithm doesn't consider un-mounting and mounting into the DOM?

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90

1 Answers1

0

does the diffing algorithm simply compare both react elements' "type" attributes?

Yes, from the docs:

Whenever the root elements have different types, React will tear down the old tree and build the new tree from scratch. Going from <a> to <img>, or from <Article> to <Comment>, or from <Button> to <div> - any of those will lead to a full rebuild.

Another your question:

So if both have the same "type", then the diffing algorithm doesn't consider un-mounting and mounting into the DOM?

Yes, in that case React just updates the existing instance. During component update instance remains the same, and state is maintained across renders.


You can see in below example:

  • The first place where we rendered A, it doesn't get unmounted when we replace it also with another A (because of same type).
  • The second place where we used A, as soon as we replace it with B, react unmounts A.

let A = (props) => {
  React.useEffect(() => {
    console.log('Mounted A', props);
    return () => {
      console.log('Unmounted A', props);
    };
  }, []);
  return <div>This is A: {props.tmp}</div>;
};

let B = (props) => {
  React.useEffect(() => {
    console.log('Mounted B', props);
    return () => {
      console.log('Unmounted B', props);
    };
  }, []);
  return <div>This is B</div>;
};

  function App() {
  let [tmp, setTemp] = React.useState(0);
  return (
    <div
      onClick={() => {
        setTemp(tmp + 1);
      }}
    >
      {tmp % 2 == 0 ? <A id="first A"/> : <A id="second A"/>}
      {tmp % 2 == 0 ? <A id="third A"/> : <B />}
      <p>Start editing to see some magic happen :)</p>
    </div>
  );
}

ReactDOM.render(<App />,document.getElementById("react"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
  • Hey Giorgi. Thanks for the help! The explanation made it a lot clearer. Just as an additional question, what exactly it mean to say that 2 react instances have the same "type"? Does it mean that they are exactly the same instance of the same react component or could they be different instances of the same react component? I'm asking because for the following code https://codesandbox.io/embed/7ko97vnv80 ,it seems to be the later. After clicking "Add Item", the diffing algorithm seems to view different react instances with the same key (note code uses index as key) as having the same type.// – Philip Dean Feb 23 '22 at 20:17
  • (Edit: My reasoning for the last sentence is because when I inspect the DOM-tree in chrome devtools, none of the old
  • tags are unmounted and re-mounted after clicking "Add Items")
  • – Philip Dean Feb 23 '22 at 20:26
  • @PhilipDean Does my modified example answer your question? – Giorgi Moniava Feb 23 '22 at 20:27
  • Ahhhh, I think I that made it more clear. So just to confirm, we say that 2 react instances have the same "type" as long as they are made from the same react component? For instance, if we created 2 different react instances of , the 2 still share the same "type"? – Philip Dean Feb 23 '22 at 20:49
  • @PhilipDean Yes that's true – Giorgi Moniava Feb 23 '22 at 20:52
  • 1
    Of course! Thanks for the help! – Philip Dean Feb 23 '22 at 21:10