text: webpackJsonp([90435031719703],{885:function(n,s){n.exports={data:{markdownRemark:{html:'<p>This section is a collection of implementation notes for the <a href="/docs/codebase-overview.html#stack-reconciler">stack reconciler</a>.</p>\n<p>It is very technical and assumes a strong understanding of React public API as well as how it’s divided into core, renderers, and the reconciler. If you’re not very familiar with the React codebase, read <a href="/docs/codebase-overview.html">the codebase overview</a> first.</p>\n<p>It also assumes an understanding of the <a href="/blog/2015/12/18/react-components-elements-and-instances.html">differences between React components, their instances, and elements</a>.</p>\n<p>The stack reconciler was used in React 15 and earlier. It is located at <a href="https://github.com/facebook/react/tree/15-stable/src/renderers/shared/stack/reconciler">src/renderers/shared/stack/reconciler</a>.</p>\n<h3 id="video-building-react-from-scratch"><a href="#video-building-react-from-scratch" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Video: Building React from Scratch</h3>\n<p><a href="https://twitter.com/zpao">Paul O’Shannessy</a> gave a talk about <a href="https://www.youtube.com/watch?v=_MAD4Oly9yg">building React from scratch</a> that largely inspired this document.</p>\n<p>Both this document and his talk are simplifications of the real codebase so you might get a better understanding by getting familiar with both of them.</p>\n<h3 id="overview"><a href="#overview" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Overview</h3>\n<p>The reconciler itself doesn’t have a public API. <a href="/docs/codebase-overview.html#stack-renderers">Renderers</a> like React DOM and React Native use it to efficiently update the user interface according to the React components written by the user.</p>\n<h3 id="mounting-as-a-recursive-process"><a href="#mounting-as-a-recursive-process" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mounting as a Recursive Process</h3>\n<p>Let’s consider the first time you mount a component:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx">ReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> rootEl<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>\n      </div>\n<p>React DOM will pass <code class="gatsby-code-text">&lt;App /&gt;</code> along to the reconciler. Remember that <code class="gatsby-code-text">&lt;App /&gt;</code> is a React element, that is, a description of <em>what</em> to render. You can think about it as a plain object:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token comment">// { type: App, props: {} }</span></code></pre>\n      </div>\n<p>The reconciler will check if <code class="gatsby-code-text">App</code> is a class or a function.</p>\n<p>If <code class="gatsby-code-text">App</code> is a function, the reconciler will call <code class="gatsby-code-text">App(props)</code> to get the rendered element.</p>\n<p>If <code class="gatsby-code-text">App</code> is a class, the reconciler will instantiate an <code class="gatsby-code-text">App</code> with <code class="gatsby-code-text">new App(props)</code>, call the <code class="gatsby-code-text">componentWillMount()</code> lifecycle method, and then will call the <code class="gatsby-code-text">render()</code> method to get the rendered element.</p>\n<p>Either way, the reconciler will learn the element <code class="gatsby-code-text">App</code> “rendered to”.</p>\n<p>This process is recursive. <code class="gatsby-code-text">App</code> may render to a <code class="gatsby-code-text">&lt;Greeting /&gt;</code>, <code class="gatsby-code-text">Greeting</code> may render to a <code class="gatsby-code-text">&lt;Button /&gt;</code>, and so on. The reconciler will “drill down” through user-defined components recursively as it learns what each component renders to.</p>\n<p>You can imagine this process as a pseudocode:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">function</span> <span class="token function">isClass</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token comment">// React.Component subclasses have this flag</span>\n  <span class="token keyword">return</span> <span class="token punctuation">(</span>\n    <span class="token function">Boolean</span><span class="token punctuation">(</span>type<span class="token punctuation">.</span>prototype<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>\n    <span class="token function">Boolean</span><span class="token punctuation">(</span>type<span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>isReactComponent<span class="token punctuation">)</span>\n  <span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n\n<span class="token comment">// This function takes a React element (e.g. &lt;App />)</span>\n<span class="token comment">// and returns a DOM or Native node representing the mounted tree.</span>\n<span class="token keyword">function</span> <span class="token function">mount</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token keyword">var</span> type <span class="token operator">=</span> element<span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n  <span class="token keyword">var</span> props <span class="token operator">=</span> element<span class="token punctuation">.</span>props<span class="token punctuation">;</span>\n\n  <span class="token comment">// We will determine the rendered element</span>\n  <span class="token comment">// by either running the type as function</span>\n  <span class="token comment">// or creating an instance and calling render().</span>\n  <span class="token keyword">var</span> renderedElement<span class="token punctuation">;</span>\n  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isClass</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Component class</span>\n    <span class="token keyword">var</span> publicInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">type</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token comment">// Set the props</span>\n    publicInstance<span class="token punctuation">.</span>props <span class="token operator">=</span> props<span class="token punctuation">;</span>\n    <span class="token comment">// Call the lifecycle if necessary</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>publicInstance<span class="token punctuation">.</span>componentWillMount<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      publicInstance<span class="token punctuation">.</span><span class="token function">componentWillMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    <span class="token comment">// Get the rendered element by calling render()</span>\n    renderedElement <span class="token operator">=</span> publicInstance<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Component function</span>\n    renderedElement <span class="token operator">=</span> <span class="token function">type</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n\n  <span class="token comment">// This process is recursive because a component may</span>\n  <span class="token comment">// return an element with a type of another component.</span>\n  <span class="token keyword">return</span> <span class="token function">mount</span><span class="token punctuation">(</span>renderedElement<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// Note: this implementation is incomplete and recurses infinitely!</span>\n  <span class="token comment">// It only handles elements like &lt;App /> or &lt;Button />.</span>\n  <span class="token comment">// It doesn\'t handle elements like &lt;div /> or &lt;p /> yet.</span>\n<span class="token punctuation">}</span>\n\n<span class="token keyword">var</span> rootEl <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">\'root\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">var</span> node <span class="token operator">=</span> <span class="token function">mount</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>\nrootEl<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>\n      </div>\n<blockquote>\n<p><strong>Note:</strong></p>\n<p>This really <em>is</em> a pseudo-code. It isn’t similar to the real implementation. It will also cause a stack overflow because we haven’t discussed when to stop the recursion.</p>\n</blockquote>\n<p>Let’s recap a few key ideas in the example above:</p>\n<ul>\n<li>React elements are plain objects representing the component type (e.g. <code class="gatsby-code-text">App</code>) and the props.</li>\n<li>User-defined components (e.g. <code class="gatsby-code-text">App</code>) can be classes or functions but they all “render to” elements.</li>\n<li>“Mounting” is a recursive process that creates a DOM or Native tree given the top-level React element (e.g. <code class="gatsby-code-text">&lt;App /&gt;</code>).</li>\n</ul>\n<h3 id="mounting-host-elements"><a href="#mounting-host-elements" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mounting Host Elements</h3>\n<p>This process would be useless if we didn’t render something to the screen as a result.</p>\n<p>In addition to user-defined (“composite”) components, React elements may also represent platform-specific (“host”) components. For example, <code class="gatsby-code-text">Button</code> might return a <code class="gatsby-code-text">&lt;div /&gt;</code> from its render method.</p>\n<p>If element’s <code class="gatsby-code-text">type</code> property is a string, we are dealing with a host element:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token comment">// { type: \'div\', props: {} }</span></code></pre>\n      </div>\n<p>There is no user-defined code associated with host elements.</p>\n<p>When the reconciler encounters a host element, it lets the renderer take care of mounting it. For example, React DOM would create a DOM node.</p>\n<p>If the host element has children, the reconciler recursively mounts them following the same algorithm as above. It doesn’t matter whether children are host (like <code class="gatsby-code-text">&lt;div&gt;&lt;hr /&gt;&lt;/div&gt;</code>), composite (like <code class="gatsby-code-text">&lt;div&gt;&lt;Button /&gt;&lt;/div&gt;</code>), or both.</p>\n<p>The DOM nodes produced by the child components will be appended to the parent DOM node, and recursively, the complete DOM structure will be assembled.</p>\n<blockquote>\n<p><strong>Note:</strong></p>\n<p>The reconciler itself is not tied to the DOM. The exact result of mounting (sometimes called “mount image” in the source code) depends on the renderer, and can be a DOM node (React DOM), a string (React DOM Server), or a number representing a native view (React Native).</p>\n</blockquote>\n<p>If we were to extend the code to handle host elements, it would look like this:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">function</span> <span class="token function">isClass</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token comment">// React.Component subclasses have this flag</span>\n  <span class="token keyword">return</span> <span class="token punctuation">(</span>\n    <span class="token function">Boolean</span><span class="token punctuation">(</span>type<span class="token punctuation">.</span>prototype<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>\n    <span class="token function">Boolean</span><span class="token punctuation">(</span>type<span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>isReactComponent<span class="token punctuation">)</span>\n  <span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n\n<span class="token comment">// This function only handles elements with a composite type.</span>\n<span class="token comment">// For example, it handles &lt;App /> and &lt;Button />, but not a &lt;div />.</span>\n<span class="token keyword">function</span> <span class="token function">mountComposite</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token keyword">var</span> type <span class="token operator">=</span> element<span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n  <span class="token keyword">var</span> props <span class="token operator">=</span> element<span class="token punctuation">.</span>props<span class="token punctuation">;</span>\n\n  <span class="token keyword">var</span> renderedElement<span class="token punctuation">;</span>\n  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isClass</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Component class</span>\n    <span class="token keyword">var</span> publicInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">type</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token comment">// Set the props</span>\n    publicInstance<span class="token punctuation">.</span>props <span class="token operator">=</span> props<span class="token punctuation">;</span>\n    <span class="token comment">// Call the lifecycle if necessary</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>publicInstance<span class="token punctuation">.</span>componentWillMount<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      publicInstance<span class="token punctuation">.</span><span class="token function">componentWillMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    renderedElement <span class="token operator">=</span> publicInstance<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> type <span class="token operator">===</span> <span class="token string">\'function\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Component function</span>\n    renderedElement <span class="token operator">=</span> <span class="token function">type</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n\n  <span class="token comment">// This is recursive but we\'ll eventually reach the bottom of recursion when</span>\n  <span class="token comment">// the element is host (e.g. &lt;div />) rather than composite (e.g. &lt;App />):</span>\n  <span class="token keyword">return</span> <span class="token function">mount</span><span class="token punctuation">(</span>renderedElement<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n\n<span class="token comment">// This function only handles elements with a host type.</span>\n<span class="token comment">// For example, it handles &lt;div /> and &lt;p /> but not an &lt;App />.</span>\n<span class="token keyword">function</span> <span class="token function">mountHost</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token keyword">var</span> type <span class="token operator">=</span> element<span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n  <span class="token keyword">var</span> props <span class="token operator">=</span> element<span class="token punctuation">.</span>props<span class="token punctuation">;</span>\n  <span class="token keyword">var</span> children <span class="token operator">=</span> props<span class="token punctuation">.</span>children <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>\n  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>children<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    children <span class="token operator">=</span> <span class="token punctuation">[</span>children<span class="token punctuation">]</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n  children <span class="token operator">=</span> children<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>Boolean<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// This block of code shouldn\'t be in the reconciler.</span>\n  <span class="token comment">// Different renderers might initialize nodes differently.</span>\n  <span class="token comment">// For example, React Native would create iOS or Android views.</span>\n  <span class="token keyword">var</span> node <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>propName <span class="token operator">=></span> <span class="token punctuation">{</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>propName <span class="token operator">!==</span> <span class="token string">\'children\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      node<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span>propName<span class="token punctuation">,</span> props<span class="token punctuation">[</span>propName<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// Mount the children</span>\n  children<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>childElement <span class="token operator">=></span> <span class="token punctuation">{</span>\n    <span class="token comment">// Children may be host (e.g. &lt;div />) or composite (e.g. &lt;Button />).</span>\n    <span class="token comment">// We will also mount them recursively:</span>\n    <span class="token keyword">var</span> childNode <span class="token operator">=</span> <span class="token function">mount</span><span class="token punctuation">(</span>childElement<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// This line of code is also renderer-specific.</span>\n    <span class="token comment">// It would be different depending on the renderer:</span>\n    node<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>childNode<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// Return the DOM node as mount result.</span>\n  <span class="token comment">// This is where the recursion ends.</span>\n  <span class="token keyword">return</span> node<span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n\n<span class="token keyword">function</span> <span class="token function">mount</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token keyword">var</span> type <span class="token operator">=</span> element<span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> type <span class="token operator">===</span> <span class="token string">\'function\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// User-defined components</span>\n    <span class="token keyword">return</span> <span class="token function">mountComposite</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> type <span class="token operator">===</span> <span class="token string">\'string\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Platform-specific components</span>\n    <span class="token keyword">return</span> <span class="token function">mountHost</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span>\n\n<span class="token keyword">var</span> rootEl <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">\'root\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">var</span> node <span class="token operator">=</span> <span class="token function">mount</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>\nrootEl<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>\n      </div>\n<p>This is working but still far from how the reconciler is really implemented. The key missing ingredient is support for updates.</p>\n<h3 id="introducing-internal-instances"><a href="#introducing-internal-instances" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Introducing Internal Instances</h3>\n<p>The key feature of React is that you can re-render everything, and it won’t recreate the DOM or reset the state:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx">ReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> rootEl<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token comment">// Should reuse the existing DOM:</span>\nReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> rootEl<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>\n      </div>\n<p>However, our implementation above only knows how to mount the initial tree. It can’t perform updates on it because it doesn’t store all the necessary information, such as all the <code class="gatsby-code-text">publicInstance</code>s, or which DOM <code class="gatsby-code-text">node</code>s correspond to which components.</p>\n<p>The stack reconciler codebase solves this by making the <code class="gatsby-code-text">mount()</code> function a method and putting it on a class. There are drawbacks to this approach, and we are going in the opposite direction in the <a href="/docs/codebase-overview.html#fiber-reconciler">ongoing rewrite of the reconciler</a>. Nevertheless this is how it works now.</p>\n<p>Instead of separate <code class="gatsby-code-text">mountHost</code> and <code class="gatsby-code-text">mountComposite</code> functions, we will create two classes: <code class="gatsby-code-text">DOMComponent</code> and <code class="gatsby-code-text">CompositeComponent</code>.</p>\n<p>Both classes have a constructor accepting the <code class="gatsby-code-text">element</code>, as well as a <code class="gatsby-code-text">mount()</code> method returning the mounted node. We will replace a top-level <code class="gatsby-code-text">mount()</code> function with a factory that instantiates the correct class:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">function</span> <span class="token function">instantiateComponent</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token keyword">var</span> type <span class="token operator">=</span> element<span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> type <span class="token operator">===</span> <span class="token string">\'function\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// User-defined components</span>\n    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">CompositeComponent</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> type <span class="token operator">===</span> <span class="token string">\'string\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Platform-specific components</span>\n    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">DOMComponent</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>  \n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>First, let’s consider the implementation of <code class="gatsby-code-text">CompositeComponent</code>:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">CompositeComponent</span> <span class="token punctuation">{</span>\n  <span class="token function">constructor</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>currentElement <span class="token operator">=</span> element<span class="token punctuation">;</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>renderedComponent <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>publicInstance <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n\n  <span class="token function">getPublicInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// For composite components, expose the class instance.</span>\n    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>publicInstance<span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n\n  <span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token keyword">var</span> element <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currentElement<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> type <span class="token operator">=</span> element<span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> props <span class="token operator">=</span> element<span class="token punctuation">.</span>props<span class="token punctuation">;</span>\n\n    <span class="token keyword">var</span> publicInstance<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> renderedElement<span class="token punctuation">;</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isClass</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token comment">// Component class</span>\n      publicInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">type</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token comment">// Set the props</span>\n      publicInstance<span class="token punctuation">.</span>props <span class="token operator">=</span> props<span class="token punctuation">;</span>\n      <span class="token comment">// Call the lifecycle if necessary</span>\n      <span class="token keyword">if</span> <span class="token punctuation">(</span>publicInstance<span class="token punctuation">.</span>componentWillMount<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        publicInstance<span class="token punctuation">.</span><span class="token function">componentWillMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n      renderedElement <span class="token operator">=</span> publicInstance<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> type <span class="token operator">===</span> <span class="token string">\'function\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token comment">// Component function</span>\n      publicInstance <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>\n      renderedElement <span class="token operator">=</span> <span class="token function">type</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token comment">// Save the public instance</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>publicInstance <span class="token operator">=</span> publicInstance<span class="token punctuation">;</span>\n\n    <span class="token comment">// Instantiate the child internal instance according to the element.</span>\n    <span class="token comment">// It would be a DOMComponent for &lt;div /> or &lt;p />,</span>\n    <span class="token comment">// and a CompositeComponent for &lt;App /> or &lt;Button />:</span>\n    <span class="token keyword">var</span> renderedComponent <span class="token operator">=</span> <span class="token function">instantiateComponent</span><span class="token punctuation">(</span>renderedElement<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>renderedComponent <span class="token operator">=</span> renderedComponent<span class="token punctuation">;</span>\n\n    <span class="token comment">// Mount the rendered output</span>\n    <span class="token keyword">return</span> renderedComponent<span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>This is not much different from our previous <code class="gatsby-code-text">mountComposite()</code> implementation, but now we can save some information, such as <code class="gatsby-code-text">this.currentElement</code>, <code class="gatsby-code-text">this.renderedComponent</code>, and <code class="gatsby-code-text">this.publicInstance</code>, for use during updates.</p>\n<p>Note that an instance of <code class="gatsby-code-text">CompositeComponent</code> is not the same thing as an instance of the user-supplied <code class="gatsby-code-text">element.type</code>. <code class="gatsby-code-text">CompositeComponent</code> is an implementation detail of our reconciler, and is never exposed to the user. The user-defined class is the one we read from <code class="gatsby-code-text">element.type</code>, and <code class="gatsby-code-text">CompositeComponent</code> creates an instance of it.</p>\n<p>To avoid the confusion, we will call instances of <code class="gatsby-code-text">CompositeComponent</code> and <code class="gatsby-code-text">DOMComponent</code> “internal instances”. They exist so we can associate some long-lived data with them. Only the renderer and the reconciler are aware that they exist.</p>\n<p>In contrast, we call an instance of the user-defined class a “public instance”. The public instance is what you see as <code class="gatsby-code-text">this</code> in the <code class="gatsby-code-text">render()</code> and other methods of your custom components.</p>\n<p>The <code class="gatsby-code-text">mountHost()</code> function, refactored to be a <code class="gatsby-code-text">mount()</code> method on <code class="gatsby-code-text">DOMComponent</code> class, also looks familiar:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">DOMComponent</span> <span class="token punctuation">{</span>\n  <span class="token function">constructor</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>currentElement <span class="token operator">=</span> element<span class="token punctuation">;</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>renderedChildren <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>node <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n\n  <span class="token function">getPublicInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// For DOM components, only expose the DOM node.</span>\n    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>node<span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n\n  <span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token keyword">var</span> element <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currentElement<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> type <span class="token operator">=</span> element<span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> props <span class="token operator">=</span> element<span class="token punctuation">.</span>props<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> children <span class="token operator">=</span> props<span class="token punctuation">.</span>children <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>children<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      children <span class="token operator">=</span> <span class="token punctuation">[</span>children<span class="token punctuation">]</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token comment">// Create and save the node</span>\n    <span class="token keyword">var</span> node <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>node <span class="token operator">=</span> node<span class="token punctuation">;</span>\n\n    <span class="token comment">// Set the attributes</span>\n    Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>propName <span class="token operator">=></span> <span class="token punctuation">{</span>\n      <span class="token keyword">if</span> <span class="token punctuation">(</span>propName <span class="token operator">!==</span> <span class="token string">\'children\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        node<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span>propName<span class="token punctuation">,</span> props<span class="token punctuation">[</span>propName<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// Create and save the contained children.</span>\n    <span class="token comment">// Each of them can be a DOMComponent or a CompositeComponent,</span>\n    <span class="token comment">// depending on whether the element type is a string or a function.</span>\n    <span class="token keyword">var</span> renderedChildren <span class="token operator">=</span> children<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>instantiateComponent<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>renderedChildren <span class="token operator">=</span> renderedChildren<span class="token punctuation">;</span>\n\n    <span class="token comment">// Collect DOM nodes they return on mount</span>\n    <span class="token keyword">var</span> childNodes <span class="token operator">=</span> renderedChildren<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>child <span class="token operator">=></span> child<span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    childNodes<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>childNode <span class="token operator">=></span> node<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>childNode<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// Return the DOM node as mount result</span>\n    <span class="token keyword">return</span> node<span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>The main difference after refactoring from <code class="gatsby-code-text">mountHost()</code> is that we now keep <code class="gatsby-code-text">this.node</code> and <code class="gatsby-code-text">this.renderedChildren</code> associated with the internal DOM component instance. We will also use them for applying non-destructive updates in the future.</p>\n<p>As a result, each internal instance, composite or host, now points to its child internal instances. To help visualize this, if a functional <code class="gatsby-code-text">&lt;App&gt;</code> component renders a <code class="gatsby-code-text">&lt;Button&gt;</code> class component, and <code class="gatsby-code-text">Button</code> class renders a <code class="gatsby-code-text">&lt;div&gt;</code>, the internal instance tree would look like this:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token punctuation">[</span>object CompositeComponent<span class="token punctuation">]</span> <span class="token punctuation">{</span>\n  currentElement<span class="token punctuation">:</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span>\n  publicInstance<span class="token punctuation">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span>\n  renderedComponent<span class="token punctuation">:</span> <span class="token punctuation">[</span>object CompositeComponent<span class="token punctuation">]</span> <span class="token punctuation">{</span>\n    currentElement<span class="token punctuation">:</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Button</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span>\n    publicInstance<span class="token punctuation">:</span> <span class="token punctuation">[</span>object Button<span class="token punctuation">]</span><span class="token punctuation">,</span>\n    renderedComponent<span class="token punctuation">:</span> <span class="token punctuation">[</span>object DOMComponent<span class="token punctuation">]</span> <span class="token punctuation">{</span>\n      currentElement<span class="token punctuation">:</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span>\n      node<span class="token punctuation">:</span> <span class="token punctuation">[</span>object HTMLDivElement<span class="token punctuation">]</span><span class="token punctuation">,</span>\n      renderedChildren<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>\n    <span class="token punctuation">}</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>In the DOM you would only see the <code class="gatsby-code-text">&lt;div&gt;</code>. However the internal instance tree contains both composite and host internal instances.</p>\n<p>The composite internal instances need to store:</p>\n<ul>\n<li>The current element.</li>\n<li>The public instance if element type is a class.</li>\n<li>The single rendered internal instance. It can be either a <code class="gatsby-code-text">DOMComponent</code> or a <code class="gatsby-code-text">CompositeComponent</code>.</li>\n</ul>\n<p>The host internal instances need to store:</p>\n<ul>\n<li>The current element.</li>\n<li>The DOM node.</li>\n<li>All the child internal instances. Each of them can be either a <code class="gatsby-code-text">DOMComponent</code> or a <code class="gatsby-code-text">CompositeComponent</code>.</li>\n</ul>\n<p>If you’re struggling to imagine how an internal instance tree is structured in more complex applications, <a href="https://github.com/facebook/react-devtools">React DevTools</a> can give you a close approximation, as it highlights host instances with grey, and composite instances with purple:</p>\n\n  <a class="gatsby-resp-image-link" href="/static/implementation-notes-tree-d96fec10d250eace9756f09543bf5d58-a6f54.png" style="display: block" target="_blank" rel="noopener">\n  \n  <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; ; max-width: 840px; margin-left: auto; margin-right: auto;">\n    <span class="gatsby-resp-image-background-image" style="padding-bottom: 62%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsSAAALEgHS3X78AAABaUlEQVQoz5VSa2/bMAzM//9vBTo08VwvWWw5kmW9n7Ysy/LUNliBtii2A8Uv0pHHow5CCkIJF5wyap1dYkzbtv8bDuu6soGNV1w9nC71haBejNA7Z50LPuS8v0Z+yx/JKaURYPQM/ehy2Lfogx4mr+fZxXne87edy0lb0lYbqx3rJVdoiH0/XS62A+52myjVbXsVQgAAlFLGmNLvnVz0KKk454vXSwjOrcZEKRetojVpCatSMszBWru84q/+w5azZZaeCamxRWbm/qXcXW7JW36J/W32j7JDCGQsfjM+INk1sqsUbht4amjdiWuFjz/x8fH2UI8V4NfiRYpxWYrL6S67gBCChkEQCM8/4PmpfX489U8Nrlv6+xepG1JX49F4MTEoR8CYKSPcyTFGhNCABsZY23Yd6GlxSWkpZPHi84beZZe78k+YYNbbL999Oe2d7JnDZ4wqaKHJKX/Gd3uOU/TEaaA0kPt/4g+zabJ6VKVk0QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;">\n      <img class="gatsby-resp-image-image" style="width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;" alt="React DevTools tree" title="" src="/static/implementation-notes-tree-d96fec10d250eace9756f09543bf5d58-acf85.png" srcset="/static/implementation-notes-tree-d96fec10d250eace9756f09543bf5d58-c1418.png 210w,\n/static/implementation-notes-tree-d96fec10d250eace9756f09543bf5d58-5d5d8.png 420w,\n/static/implementation-notes-tree-d96fec10d250eace9756f09543bf5d58-acf85.png 840w,\n/static/implementation-notes-tree-d96fec10d250eace9756f09543bf5d58-a6f54.png 1000w" sizes="(max-width: 840px) 100vw, 840px">\n    </span>\n  </span>\n  \n  </a>\n    \n<p>To complete this refactoring, we will introduce a function that mounts a complete tree into a container node, just like <code class="gatsby-code-text">ReactDOM.render()</code>. It returns a public instance, also like <code class="gatsby-code-text">ReactDOM.render()</code>:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">function</span> <span class="token function">mountTree</span><span class="token punctuation">(</span>element<span class="token punctuation">,</span> containerNode<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token comment">// Create the top-level internal instance</span>\n  <span class="token keyword">var</span> rootComponent <span class="token operator">=</span> <span class="token function">instantiateComponent</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// Mount the top-level component into the container</span>\n  <span class="token keyword">var</span> node <span class="token operator">=</span> rootComponent<span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  containerNode<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// Return the public instance it provides</span>\n  <span class="token keyword">var</span> publicInstance <span class="token operator">=</span> rootComponent<span class="token punctuation">.</span><span class="token function">getPublicInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token keyword">return</span> publicInstance<span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n\n<span class="token keyword">var</span> rootEl <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">\'root\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token function">mountTree</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> rootEl<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>\n      </div>\n<h3 id="unmounting"><a href="#unmounting" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Unmounting</h3>\n<p>Now that we have internal instances that hold onto their children and the DOM nodes, we can implement unmounting. For a composite component, unmounting calls a lifecycle hook and recurses.</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">CompositeComponent</span> <span class="token punctuation">{</span>\n\n  <span class="token comment">// ...</span>\n\n  <span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Call the lifecycle hook if necessary</span>\n    <span class="token keyword">var</span> publicInstance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>publicInstance<span class="token punctuation">;</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>publicInstance<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token keyword">if</span> <span class="token punctuation">(</span>publicInstance<span class="token punctuation">.</span>componentWillUnmount<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        publicInstance<span class="token punctuation">.</span><span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token comment">// Unmount the single rendered component</span>\n    <span class="token keyword">var</span> renderedComponent <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>renderedComponent<span class="token punctuation">;</span>\n    renderedComponent<span class="token punctuation">.</span><span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>For <code class="gatsby-code-text">DOMComponent</code>, unmounting tells each child to unmount:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">DOMComponent</span> <span class="token punctuation">{</span>\n\n  <span class="token comment">// ...</span>\n\n  <span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Unmount all the children</span>\n    <span class="token keyword">var</span> renderedChildren <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>renderedChildren<span class="token punctuation">;</span>\n    renderedChildren<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>child <span class="token operator">=></span> child<span class="token punctuation">.</span><span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>In practice, unmounting DOM components also removes the event listeners and clears some caches, but we will skip those details.</p>\n<p>We can now add a new top-level function called <code class="gatsby-code-text">unmountTree(containerNode)</code> that is similar to <code class="gatsby-code-text">ReactDOM.unmountComponentAtNode()</code>:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">function</span> <span class="token function">unmountTree</span><span class="token punctuation">(</span>containerNode<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token comment">// Read the internal instance from a DOM node:</span>\n  <span class="token comment">// (This doesn\'t work yet, we will need to change mountTree() to store it.)</span>\n  <span class="token keyword">var</span> node <span class="token operator">=</span> containerNode<span class="token punctuation">.</span>firstChild<span class="token punctuation">;</span>\n  <span class="token keyword">var</span> rootComponent <span class="token operator">=</span> node<span class="token punctuation">.</span>_internalInstance<span class="token punctuation">;</span>\n\n  <span class="token comment">// Unmount the tree and clear the container</span>\n  rootComponent<span class="token punctuation">.</span><span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  containerNode<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">\'\'</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>In order for this to work, we need to read an internal root instance from a DOM node. We will modify <code class="gatsby-code-text">mountTree()</code> to add the <code class="gatsby-code-text">_internalInstance</code> property to the root DOM node. We will also teach <code class="gatsby-code-text">mountTree()</code> to destroy any existing tree so it can be called multiple times:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">function</span> <span class="token function">mountTree</span><span class="token punctuation">(</span>element<span class="token punctuation">,</span> containerNode<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token comment">// Destroy any existing tree</span>\n  <span class="token keyword">if</span> <span class="token punctuation">(</span>containerNode<span class="token punctuation">.</span>firstChild<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token function">unmountTree</span><span class="token punctuation">(</span>containerNode<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n\n  <span class="token comment">// Create the top-level internal instance</span>\n  <span class="token keyword">var</span> rootComponent <span class="token operator">=</span> <span class="token function">instantiateComponent</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// Mount the top-level component into the container</span>\n  <span class="token keyword">var</span> node <span class="token operator">=</span> rootComponent<span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  containerNode<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// Save a reference to the internal instance</span>\n  node<span class="token punctuation">.</span>_internalInstance <span class="token operator">=</span> rootComponent<span class="token punctuation">;</span>\n\n  <span class="token comment">// Return the public instance it provides</span>\n  <span class="token keyword">var</span> publicInstance <span class="token operator">=</span> rootComponent<span class="token punctuation">.</span><span class="token function">getPublicInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token keyword">return</span> publicInstance<span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>Now, running <code class="gatsby-code-text">unmountTree()</code>, or running <code class="gatsby-code-text">mountTree()</code> repeatedly, removes the old tree and runs the <code class="gatsby-code-text">componentWillUnmount()</code> lifecycle hook on components.</p>\n<h3 id="updating"><a href="#updating" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Updating</h3>\n<p>In the previous section, we implemented unmounting. However React wouldn’t be very useful if each prop change unmounted and mounted the whole tree. The goal of the reconciler is to reuse existing instances where possible to preserve the DOM and the state:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">var</span> rootEl <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">\'root\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token function">mountTree</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> rootEl<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token comment">// Should reuse the existing DOM:</span>\n<span class="token function">mountTree</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> rootEl<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>\n      </div>\n<p>We will extend our internal instance contract with one more method. In addition to <code class="gatsby-code-text">mount()</code> and <code class="gatsby-code-text">unmount()</code>, both <code class="gatsby-code-text">DOMComponent</code> and <code class="gatsby-code-text">CompositeComponent</code> will implement a new method called <code class="gatsby-code-text">receive(nextElement)</code>:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">CompositeComponent</span> <span class="token punctuation">{</span>\n  <span class="token comment">// ...</span>\n\n  <span class="token function">receive</span><span class="token punctuation">(</span>nextElement<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// ...</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span>\n\n<span class="token keyword">class</span> <span class="token class-name">DOMComponent</span> <span class="token punctuation">{</span>\n  <span class="token comment">// ...</span>\n\n  <span class="token function">receive</span><span class="token punctuation">(</span>nextElement<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// ...</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>Its job is to do whatever is necessary to bring the component (and any of its children) up to date with the description provided by the <code class="gatsby-code-text">nextElement</code>.</p>\n<p>This is the part that is often described as “virtual DOM diffing” although what really happens is that we walk the internal tree recursively and let each internal instance receive an update.</p>\n<h3 id="updating-composite-components"><a href="#updating-composite-components" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Updating Composite Components</h3>\n<p>When a composite component receives a new element, we run the <code class="gatsby-code-text">componentWillUpdate()</code> lifecycle hook.</p>\n<p>Then we re-render the component with the new props, and get the next rendered element:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">CompositeComponent</span> <span class="token punctuation">{</span>\n\n  <span class="token comment">// ...</span>\n\n  <span class="token function">receive</span><span class="token punctuation">(</span>nextElement<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token keyword">var</span> prevProps <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currentElement<span class="token punctuation">.</span>props<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> publicInstance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>publicInstance<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> prevRenderedComponent <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>renderedComponent<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> prevRenderedElement <span class="token operator">=</span> prevRenderedComponent<span class="token punctuation">.</span>currentElement<span class="token punctuation">;</span>\n\n    <span class="token comment">// Update *own* element</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>currentElement <span class="token operator">=</span> nextElement<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> type <span class="token operator">=</span> nextElement<span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> nextProps <span class="token operator">=</span> nextElement<span class="token punctuation">.</span>props<span class="token punctuation">;</span>\n\n    <span class="token comment">// Figure out what the next render() output is</span>\n    <span class="token keyword">var</span> nextRenderedElement<span class="token punctuation">;</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isClass</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token comment">// Component class</span>\n      <span class="token comment">// Call the lifecycle if necessary</span>\n      <span class="token keyword">if</span> <span class="token punctuation">(</span>publicInstance<span class="token punctuation">.</span>componentWillUpdate<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        publicInstance<span class="token punctuation">.</span><span class="token function">componentWillUpdate</span><span class="token punctuation">(</span>nextProps<span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n      <span class="token comment">// Update the props</span>\n      publicInstance<span class="token punctuation">.</span>props <span class="token operator">=</span> nextProps<span class="token punctuation">;</span>\n      <span class="token comment">// Re-render</span>\n      nextRenderedElement <span class="token operator">=</span> publicInstance<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> type <span class="token operator">===</span> <span class="token string">\'function\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token comment">// Component function</span>\n      nextRenderedElement <span class="token operator">=</span> <span class="token function">type</span><span class="token punctuation">(</span>nextProps<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token comment">// ...</span></code></pre>\n      </div>\n<p>Next, we can look at the rendered element’s <code class="gatsby-code-text">type</code>. If the <code class="gatsby-code-text">type</code> has not changed since the last render, the component below can also be updated in place.</p>\n<p>For example, if it returned <code class="gatsby-code-text">&lt;Button color=&quot;red&quot; /&gt;</code> the first time, and <code class="gatsby-code-text">&lt;Button color=&quot;blue&quot; /&gt;</code> the second time, we can just tell the corresponding internal instance to <code class="gatsby-code-text">receive()</code> the next element:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx">    <span class="token comment">// ...</span>\n\n    <span class="token comment">// If the rendered element type has not changed,</span>\n    <span class="token comment">// reuse the existing component instance and exit.</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>prevRenderedElement<span class="token punctuation">.</span>type <span class="token operator">===</span> nextRenderedElement<span class="token punctuation">.</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      prevRenderedComponent<span class="token punctuation">.</span><span class="token function">receive</span><span class="token punctuation">(</span>nextRenderedElement<span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token keyword">return</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token comment">// ...</span></code></pre>\n      </div>\n<p>However, if the next rendered element has a different <code class="gatsby-code-text">type</code> than the previously rendered element, we can’t update the internal instance. A <code class="gatsby-code-text">&lt;button&gt;</code> can’t “become” an <code class="gatsby-code-text">&lt;input&gt;</code>.</p>\n<p>Instead, we have to unmount the existing internal instance and mount the new one corresponding to the rendered element type. For example, this is what happens when a component that previously rendered a <code class="gatsby-code-text">&lt;button /&gt;</code> renders an <code class="gatsby-code-text">&lt;input /&gt;</code>:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx">    <span class="token comment">// ...</span>\n\n    <span class="token comment">// If we reached this point, we need to unmount the previously</span>\n    <span class="token comment">// mounted component, mount the new one, and swap their nodes.</span>\n\n    <span class="token comment">// Find the old node because it will need to be replaced</span>\n    <span class="token keyword">var</span> prevNode <span class="token operator">=</span> prevRenderedComponent<span class="token punctuation">.</span><span class="token function">getHostNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// Unmount the old child and mount a new child</span>\n    prevRenderedComponent<span class="token punctuation">.</span><span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token keyword">var</span> nextRenderedComponent <span class="token operator">=</span> <span class="token function">instantiateComponent</span><span class="token punctuation">(</span>nextRenderedElement<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token keyword">var</span> nextNode <span class="token operator">=</span> nextRenderedComponent<span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// Replace the reference to the child</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>renderedComponent <span class="token operator">=</span> nextRenderedComponent<span class="token punctuation">;</span>\n\n    <span class="token comment">// Replace the old node with the new one</span>\n    <span class="token comment">// Note: this is renderer-specific code and</span>\n    <span class="token comment">// ideally should live outside of CompositeComponent:</span>\n    prevNode<span class="token punctuation">.</span>parentNode<span class="token punctuation">.</span><span class="token function">replaceChild</span><span class="token punctuation">(</span>nextNode<span class="token punctuation">,</span> prevNode<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>To sum this up, when a composite component receives a new element, it may either delegate the update to its rendered internal instance, or unmount it and mount a new one in its place.</p>\n<p>There is another condition under which a component will re-mount rather than receive an element, and that is when the element’s <code class="gatsby-code-text">key</code> has changed. We don’t discuss <code class="gatsby-code-text">key</code> handling in this document because it adds more complexity to an already complex tutorial.</p>\n<p>Note that we needed to add a method called <code class="gatsby-code-text">getHostNode()</code> to the internal instance contract so that it’s possible to locate the platform-specific node and replace it during the update. Its implementation is straightforward for both classes:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">CompositeComponent</span> <span class="token punctuation">{</span>\n  <span class="token comment">// ...</span>\n\n  <span class="token function">getHostNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// Ask the rendered component to provide it.</span>\n    <span class="token comment">// This will recursively drill down any composites.</span>\n    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>renderedComponent<span class="token punctuation">.</span><span class="token function">getHostNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span>\n\n<span class="token keyword">class</span> <span class="token class-name">DOMComponent</span> <span class="token punctuation">{</span>\n  <span class="token comment">// ...</span>\n\n  <span class="token function">getHostNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>node<span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>  \n<span class="token punctuation">}</span></code></pre>\n      </div>\n<h3 id="updating-host-components"><a href="#updating-host-components" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Updating Host Components</h3>\n<p>Host component implementations, such as <code class="gatsby-code-text">DOMComponent</code>, update differently. When they receive an element, they need to update the underlying platform-specific view. In case of React DOM, this means updating the DOM attributes:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">DOMComponent</span> <span class="token punctuation">{</span>\n  <span class="token comment">// ...</span>\n\n  <span class="token function">receive</span><span class="token punctuation">(</span>nextElement<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token keyword">var</span> node <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>node<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> prevElement <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currentElement<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> prevProps <span class="token operator">=</span> prevElement<span class="token punctuation">.</span>props<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> nextProps <span class="token operator">=</span> nextElement<span class="token punctuation">.</span>props<span class="token punctuation">;</span>    \n    <span class="token keyword">this</span><span class="token punctuation">.</span>currentElement <span class="token operator">=</span> nextElement<span class="token punctuation">;</span>\n\n    <span class="token comment">// Remove old attributes.</span>\n    Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>prevProps<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>propName <span class="token operator">=></span> <span class="token punctuation">{</span>\n      <span class="token keyword">if</span> <span class="token punctuation">(</span>propName <span class="token operator">!==</span> <span class="token string">\'children\'</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>nextProps<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>propName<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        node<span class="token punctuation">.</span><span class="token function">removeAttribute</span><span class="token punctuation">(</span>propName<span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token comment">// Set next attributes.</span>\n    Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>nextProps<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>propName <span class="token operator">=></span> <span class="token punctuation">{</span>\n      <span class="token keyword">if</span> <span class="token punctuation">(</span>propName <span class="token operator">!==</span> <span class="token string">\'children\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        node<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span>propName<span class="token punctuation">,</span> nextProps<span class="token punctuation">[</span>propName<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// ...</span></code></pre>\n      </div>\n<p>Then, host components need to update their children. Unlike composite components, they might contain more than a single child.</p>\n<p>In this simplified example, we use an array of internal instances and iterate over it, either updating or replacing the internal instances depending on whether the received <code class="gatsby-code-text">type</code> matches their previous <code class="gatsby-code-text">type</code>. The real reconciler also takes element’s <code class="gatsby-code-text">key</code> in the account and track moves in addition to insertions and deletions, but we will omit this logic.</p>\n<p>We collect DOM operations on children in a list so we can execute them in batch:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx">    <span class="token comment">// ...</span>\n\n    <span class="token comment">// These are arrays of React elements:</span>\n    <span class="token keyword">var</span> prevChildren <span class="token operator">=</span> prevProps<span class="token punctuation">.</span>children <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>prevChildren<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      prevChildren <span class="token operator">=</span> <span class="token punctuation">[</span>prevChildren<span class="token punctuation">]</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    <span class="token keyword">var</span> nextChildren <span class="token operator">=</span> nextProps<span class="token punctuation">.</span>children <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>nextChildren<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      nextChildren <span class="token operator">=</span> <span class="token punctuation">[</span>nextChildren<span class="token punctuation">]</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    <span class="token comment">// These are arrays of internal instances:</span>\n    <span class="token keyword">var</span> prevRenderedChildren <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>renderedChildren<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> nextRenderedChildren <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// As we iterate over children, we will add operations to the array.</span>\n    <span class="token keyword">var</span> operationQueue <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// Note: the section below is extremely simplified!</span>\n    <span class="token comment">// It doesn\'t handle reorders, children with holes, or keys.</span>\n    <span class="token comment">// It only exists to illustrate the overall flow, not the specifics.</span>\n\n    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> nextChildren<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token comment">// Try to get an existing internal instance for this child</span>\n      <span class="token keyword">var</span> prevChild <span class="token operator">=</span> prevRenderedChildren<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>\n\n      <span class="token comment">// If there is no internal instance under this index,</span>\n      <span class="token comment">// a child has been appended to the end. Create a new</span>\n      <span class="token comment">// internal instance, mount it, and use its node.</span>\n      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>prevChild<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        <span class="token keyword">var</span> nextChild <span class="token operator">=</span> <span class="token function">instantiateComponent</span><span class="token punctuation">(</span>nextChildren<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n        <span class="token keyword">var</span> node <span class="token operator">=</span> nextChild<span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n        <span class="token comment">// Record that we need to append a node</span>\n        operationQueue<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span>type<span class="token punctuation">:</span> <span class="token string">\'ADD\'</span><span class="token punctuation">,</span> node<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n        nextRenderedChildren<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>nextChild<span class="token punctuation">)</span><span class="token punctuation">;</span>\n        <span class="token keyword">continue</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n\n      <span class="token comment">// We can only update the instance if its element\'s type matches.</span>\n      <span class="token comment">// For example, &lt;Button size="small" /> can be updated to</span>\n      <span class="token comment">// &lt;Button size="large" /> but not to an &lt;App />.</span>\n      <span class="token keyword">var</span> canUpdate <span class="token operator">=</span> prevChildren<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>type <span class="token operator">===</span> nextChildren<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>type<span class="token punctuation">;</span>\n\n      <span class="token comment">// If we can\'t update an existing instance, we have to unmount it</span>\n      <span class="token comment">// and mount a new one instead of it.</span>\n      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>canUpdate<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        <span class="token keyword">var</span> prevNode <span class="token operator">=</span> prevChild<span class="token punctuation">.</span><span class="token function">getHostNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n        prevChild<span class="token punctuation">.</span><span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n        <span class="token keyword">var</span> nextChild <span class="token operator">=</span> <span class="token function">instantiateComponent</span><span class="token punctuation">(</span>nextChildren<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n        <span class="token keyword">var</span> nextNode <span class="token operator">=</span> nextChild<span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n        <span class="token comment">// Record that we need to swap the nodes</span>\n        operationQueue<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span>type<span class="token punctuation">:</span> <span class="token string">\'REPLACE\'</span><span class="token punctuation">,</span> prevNode<span class="token punctuation">,</span> nextNode<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n        nextRenderedChildren<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>nextChild<span class="token punctuation">)</span><span class="token punctuation">;</span>\n        <span class="token keyword">continue</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n\n      <span class="token comment">// If we can update an existing internal instance,</span>\n      <span class="token comment">// just let it receive the next element and handle its own update.</span>\n      prevChild<span class="token punctuation">.</span><span class="token function">receive</span><span class="token punctuation">(</span>nextChildren<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n      nextRenderedChildren<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>prevChild<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token comment">// Finally, unmount any children that don\'t exist:</span>\n    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> j <span class="token operator">=</span> nextChildren<span class="token punctuation">.</span>length<span class="token punctuation">;</span> j <span class="token operator">&lt;</span> prevChildren<span class="token punctuation">.</span>length<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token keyword">var</span> prevChild <span class="token operator">=</span> prevRenderedChildren<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      <span class="token keyword">var</span> node <span class="token operator">=</span> prevChild<span class="token punctuation">.</span><span class="token function">getHostNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n      prevChild<span class="token punctuation">.</span><span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n      <span class="token comment">// Record that we need to remove the node</span>\n      operationQueue<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span>type<span class="token punctuation">:</span> <span class="token string">\'REMOVE\'</span><span class="token punctuation">,</span> node<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token comment">// Point the list of rendered children to the updated version.</span>\n    <span class="token keyword">this</span><span class="token punctuation">.</span>renderedChildren <span class="token operator">=</span> nextRenderedChildren<span class="token punctuation">;</span>\n\n    <span class="token comment">// ...</span></code></pre>\n      </div>\n<p>As the last step, we execute the DOM operations. Again, the real reconciler code is more complex because it also handles moves:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx">    <span class="token comment">// ...</span>\n\n    <span class="token comment">// Process the operation queue.</span>\n    <span class="token keyword">while</span> <span class="token punctuation">(</span>operationQueue<span class="token punctuation">.</span>length <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token keyword">var</span> operation <span class="token operator">=</span> operationQueue<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token keyword">switch</span> <span class="token punctuation">(</span>operation<span class="token punctuation">.</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token keyword">case</span> <span class="token string">\'ADD\'</span><span class="token punctuation">:</span>\n        <span class="token keyword">this</span><span class="token punctuation">.</span>node<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>operation<span class="token punctuation">.</span>node<span class="token punctuation">)</span><span class="token punctuation">;</span>\n        <span class="token keyword">break</span><span class="token punctuation">;</span>\n      <span class="token keyword">case</span> <span class="token string">\'REPLACE\'</span><span class="token punctuation">:</span>\n        <span class="token keyword">this</span><span class="token punctuation">.</span>node<span class="token punctuation">.</span><span class="token function">replaceChild</span><span class="token punctuation">(</span>operation<span class="token punctuation">.</span>nextNode<span class="token punctuation">,</span> operation<span class="token punctuation">.</span>prevNode<span class="token punctuation">)</span><span class="token punctuation">;</span>\n        <span class="token keyword">break</span><span class="token punctuation">;</span>\n      <span class="token keyword">case</span> <span class="token string">\'REMOVE\'</span><span class="token punctuation">:</span>\n        <span class="token keyword">this</span><span class="token punctuation">.</span>node<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>operation<span class="token punctuation">.</span>node<span class="token punctuation">)</span><span class="token punctuation">;</span>\n        <span class="token keyword">break</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n    <span class="token punctuation">}</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>And that is it for updating host components.</p>\n<h3 id="top-level-updates"><a href="#top-level-updates" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Top-Level Updates</h3>\n<p>Now that both <code class="gatsby-code-text">CompositeComponent</code> and <code class="gatsby-code-text">DOMComponent</code> implement the <code class="gatsby-code-text">receive(nextElement)</code> method, we can change the top-level <code class="gatsby-code-text">mountTree()</code> function to use it when the element <code class="gatsby-code-text">type</code> is the same as it was the last time:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">function</span> <span class="token function">mountTree</span><span class="token punctuation">(</span>element<span class="token punctuation">,</span> containerNode<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token comment">// Check for an existing tree</span>\n  <span class="token keyword">if</span> <span class="token punctuation">(</span>containerNode<span class="token punctuation">.</span>firstChild<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token keyword">var</span> prevNode <span class="token operator">=</span> containerNode<span class="token punctuation">.</span>firstChild<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> prevRootComponent <span class="token operator">=</span> prevNode<span class="token punctuation">.</span>_internalInstance<span class="token punctuation">;</span>\n    <span class="token keyword">var</span> prevElement <span class="token operator">=</span> prevRootComponent<span class="token punctuation">.</span>currentElement<span class="token punctuation">;</span>\n\n    <span class="token comment">// If we can, reuse the existing root component</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>prevElement<span class="token punctuation">.</span>type <span class="token operator">===</span> element<span class="token punctuation">.</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      prevRootComponent<span class="token punctuation">.</span><span class="token function">receive</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token keyword">return</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token comment">// Otherwise, unmount the existing tree</span>\n    <span class="token function">unmountTree</span><span class="token punctuation">(</span>containerNode<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token punctuation">}</span>\n\n  <span class="token comment">// ...</span>\n\n<span class="token punctuation">}</span></code></pre>\n      </div>\n<p>Now calling <code class="gatsby-code-text">mountTree()</code> two times with the same type isn’t destructive:</p>\n<div class="gatsby-highlight">\n      <pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">var</span> rootEl <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">\'root\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token function">mountTree</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> rootEl<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token comment">// Reuses the existing DOM:</span>\n<span class="token function">mountTree</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>App</span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> rootEl<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>\n      </div>\n<p>These are the basics of how React works internally.</p>\n<h3 id="what-we-left-out"><a href="#what-we-left-out" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>What We Left Out</h3>\n<p>This document is simplified compared to the real codebase. There are a few important aspects we didn’t address:</p>\n<ul>\n<li>\n<p>Components can render <code class="gatsby-code-text">null</code>, and the reconciler can handle “empty slots” in arrays and rendered output.</p>\n</li>\n<li>\n<p>The reconciler also reads <code class="gatsby-code-text">key</code> from the elements, and uses it to establish which internal instance corresponds to which element in an array. A bulk of complexity in the actual React implementation is related to that.</p>\n</li>\n<li>\n<p>In addition to composite and host internal instance classes, there are also classes for “text” and “empty” components. They represent text nodes and the “empty slots” you get by rendering <code class="gatsby-code-text">null</code>.</p>\n</li>\n<li>\n<p>Renderers use <a href="/docs/codebase-overview.html#dynamic-injection">injection</a> to pass the host internal class to the reconciler. For example, React DOM tells the reconciler to use <code class="gatsby-code-text">ReactDOMComponent</code> as the host internal instance implementation.</p>\n</li>\n<li>\n<p>The logic for updating the list of children is extracted into a mixin called <code class="gatsby-code-text">ReactMultiChild</code> which is used by the host internal instance class implementations both in React DOM and React Native.</p>\n</li>\n<li>\n<p>The reconciler also implements support for <code class="gatsby-code-text">setState()</code> in composite components. Multiple updates inside event handlers get batched into a single update.</p>\n</li>\n<li>\n<p>The reconciler also takes care of attaching and detaching refs to composite components and host nodes.</p>\n</li>\n<li>\n<p>Lifecycle hooks that are called after the DOM is ready, such as <code class="gatsby-code-text">componentDidMount()</code> and <code class="gatsby-code-text">componentDidUpdate()</code>, get collected into “callback queues” and are executed in a single batch.</p>\n</li>\n<li>\n<p>React puts information about the current update into an internal object called “transaction”. Transactions are useful for keeping track of the queue of pending lifecycle hooks, the current DOM nesting for the warnings, and anything else that is “global” to a specific update. Transactions also ensure React “cleans everything up” after updates. For example, the transaction class provided by React DOM restores the input selection after any update.</p>\n</li>\n</ul>\n<h3 id="jumping-into-the-code"><a href="#jumping-into-the-code" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Jumping into the Code</h3>\n<ul>\n<li>\n<p><a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/dom/client/ReactMount.js"><code class="gatsby-code-text">ReactMount</code></a> is where the code like <code class="gatsby-code-text">mountTree()</code> and <code class="gatsby-code-text">unmountTree()</code> from this tutorial lives. It takes care of mounting and unmounting top-level components. <a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/native/ReactNativeMount.js"><code class="gatsby-code-text">ReactNativeMount</code></a> is its React Native analog.</p>\n</li>\n<li>\n<p><a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/dom/shared/ReactDOMComponent.js"><code class="gatsby-code-text">ReactDOMComponent</code></a> is the equivalent of <code class="gatsby-code-text">DOMComponent</code> in this tutorial. It implements the host component class for React DOM renderer. <a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/native/ReactNativeBaseComponent.js"><code class="gatsby-code-text">ReactNativeBaseComponent</code></a> is its React Native analog.</p>\n</li>\n<li>\n<p><a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js"><code class="gatsby-code-text">ReactCompositeComponent</code></a> is the equivalent of <code class="gatsby-code-text">CompositeComponent</code> in this tutorial. It handles calling user-defined components and maintaining their state.</p>\n</li>\n<li>\n<p><a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/instantiateReactComponent.js"><code class="gatsby-code-text">instantiateReactComponent</code></a> contains the switch that picks the right internal instance class to construct for an element. It is equivalent to <code class="gatsby-code-text">instantiateComponent()</code> in this tutorial.</p>\n</li>\n<li>\n<p><a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactReconciler.js"><code class="gatsby-code-text">ReactReconciler</code></a> is a wrapper with <code class="gatsby-code-text">mountComponent()</code>, <code class="gatsby-code-text">receiveComponent()</code>, and <code class="gatsby-code-text">unmountComponent()</code> methods. It calls the underlying implementations on the internal instances, but also includes some code around them that is shared by all internal instance implementations.</p>\n</li>\n<li>\n<p><a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactChildReconciler.js"><code class="gatsby-code-text">ReactChildReconciler</code></a> implements the logic for mounting, updating, and unmounting children according to the <code class="gatsby-code-text">key</code> of their elements.</p>\n</li>\n<li>\n<p><a href="https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactMultiChild.js"><code class="gatsby-code-text">ReactMultiChild</code></a> implements processing the operation queue for child insertions, deletions, and moves independently of the renderer.</p>\n</li>\n<li>\n<p><code class="gatsby-code-text">mount()</code>, <code class="gatsby-code-text">receive()</code>, and <code class="gatsby-code-text">unmount()</code> are really called <code class="gatsby-code-text">mountComponent()</code>, <code class="gatsby-code-text">receiveComponent()</code>, and <code class="gatsby-code-text">unmountComponent()</code> in React codebase for legacy reasons, but they receive elements.</p>\n</li>\n<li>\n<p>Properties on the internal instances start with an underscore, e.g. <code class="gatsby-code-text">_currentElement</code>. They are considered to be read-only public fields throughout the codebase.</p>\n</li>\n</ul>\n<h3 id="future-directions"><a href="#future-directions" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Future Directions</h3>\n<p>Stack reconciler has inherent limitations such as being synchronous and unable to interrupt the work or split it in chunks. There is a work in progress on the <a href="/docs/codebase-overview.html#fiber-reconciler">new Fiber reconciler</a> with a <a href="https://github.com/acdlite/react-fiber-architecture">completely different architecture</a>. In the future, we intend to replace stack reconciler with it, but at the moment it is far from feature parity.</p>\n<h3 id="next-steps"><a href="#next-steps" aria-hidden="true" class="anchor"><svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Next Steps</h3>\n<p>Read the <a href="/docs/design-principles.html">next section</a> to learn about the guiding principles we use for React development.</p>',
  frontmatter:{title:"Implementation Notes",next:"design-principles.html",prev:"codebase-overview.html"},fields:{path:null,slug:"docs/implementation-notes.html"}}},pathContext:{slug:"docs/implementation-notes.html"}}}});
  //# sourceMappingURL=path---docs-implementation-notes-html-16ab820e2e619bd370af.js.map