<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[React In Depth - Medium]]></title>
        <description><![CDATA[The place where advanced React concepts are explained - Medium]]></description>
        <link>https://medium.com/react-in-depth?source=rss----e862e06fcbd9---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>React In Depth - Medium</title>
            <link>https://medium.com/react-in-depth?source=rss----e862e06fcbd9---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 03:28:03 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/react-in-depth" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Why React Suspense Will Be a Game Changer]]></title>
            <link>https://medium.com/react-in-depth/why-react-suspense-will-be-a-game-changer-37b40fea71ec?source=rss----e862e06fcbd9---4</link>
            <guid isPermaLink="false">https://medium.com/p/37b40fea71ec</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[suspense]]></category>
            <dc:creator><![CDATA[Julian Burr]]></dc:creator>
            <pubDate>Tue, 29 Jan 2019 09:51:43 GMT</pubDate>
            <atom:updated>2020-03-02T10:58:09.710Z</atom:updated>
            <content:encoded><![CDATA[<h4>A less technical and more conceptual in-depth overview of React Suspense and our mental model of loading states</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tweQ4csvY8_goJxMMM0Vlw.jpeg" /></figure><blockquote><a href="https://medium.com/react-in-depth"><strong><em>ReactInDepth</em></strong></a><strong><em> is moving away from Medium. </em></strong><a href="https://indepth.dev/why-react-suspense-will-be-a-game-changer/"><strong><em>This article</em></strong></a><strong><em>, its updates and more recent articles are hosted on the new platform </em></strong><a href="https://indepth.dev/"><strong><em>inDepth.dev</em></strong></a></blockquote><p>I don’t want to dig too deep into the technical details of React Suspense and how it works under the hood, there are already <a href="https://auth0.com/blog/time-slice-suspense-react16/">plenty</a> <a href="https://hackernoon.com/building-a-polyfill-for-react-suspense-f1c7baf18ca1">great</a> <a href="https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html">blog posts</a>, <a href="https://www.youtube.com/watch?v=SCQgE4mTnjU">videos</a> and <a href="https://www.youtube.com/watch?v=z-6JC0_cOns">conference talks</a> out there that do that. Instead I want to focus more on the impact Suspense will have on us application developers in the way we think about loading states and architecture our apps.</p><h3>Still, a brief technical introduction</h3><p>To get everyone who hasn’t heard about Suspense or doesn’t really know what it is on board, I still want to give at least a summary of what all this fuzz is about.</p><p>Introduced <a href="https://www.youtube.com/watch?v=nLF0n9SACd4">at JSConf Iceland</a> by Dan Abramov last year, Suspense was pitched as an improvement to the developer experience when dealing with asynchronous data fetching within React apps. This is a huge deal, because everyone who is building dynamic web applications knows that this is still one of the major pain points and one of the things that brings huge boilerplates with it.</p><p>Suspense is also supposed to transform the way we think about loading states, which shouldn’t be coupled to the fetching component or data source, but rather a UI concern. Our apps should show spinners where it makes most sense in context of the user experience. Suspense helps doing so by decoupling these concerns for us.</p><h3>Dan Abramov on Twitter</h3><p>@AdamRackis Suspense doesn&#39;t care why (or how many times) you suspend, so a single spinner can work for a combination of code splitting, data fetching, image loading, etc. Whatever the tree below needs. And if it&#39;s fast enough, then no spinner at all!</p><p>This goes beyond API data fetching and can be applied to any async data flow, e.g. code splitting or assets loading. React.lazy in combination with the Suspense component <a href="https://reactjs.org/blog/2018/10/23/react-v-16-6.html">already made it into the latest React stable release</a>, allowing easy code splitting for dynamic imports without having to manually handle the loading state. The fully featured Suspense functionality that includes data fetching will have to wait until <a href="https://reactjs.org/blog/2018/11/27/react-16-roadmap.html">later this year</a>, but you can already experiment with it through current alpha releases.</p><p>The general idea is to allow components to “suspend” their render, e.g. if they need extra data loaded from external sources. Once all the information is there, React will re-try to render the component.</p><p>To achieve this, React uses Promises. A component can throw a Promise in its render method (or <a href="https://twitter.com/acdlite/status/969428655238557697">anything that is called during the component’s render</a>, e.g. the new static getDerivedStateFromProps). React catches the thrown Promise and looks for the closest Suspense component up the tree, which acts as a sort of boundary. The Suspense component takes an element as its fallback prop, which will be rendered while <em>any</em> children in its subtree are suspended, no matter where or why.</p><p>React also keeps track of the thrown Promise. Once it resolves, another attempt of rendering the component is made. This assumes that since the Promise is resolved, the suspended component now has all the information it needs to properly render. For that, we use some form of cache where the data is stored. This cache essentially determines on every render whether the data is already available (then it just reads it like from a variable) or not, in which case it triggers the fetch and throws the resulting Promise for React to catch. As mentioned this is not exclusive to data fetching, any async action that can be described using Promises can make use of it, code splitting being a very obvious and popular example.</p><p>The core concept is very similar to <a href="https://reactjs.org/docs/error-boundaries.html">error boundaries</a>, which were introduced in React 16 to allow catching uncaught exceptions anywhere within the app by, again, placing components (in this case any component with a componentDidCatch lifecycle method) in your tree to handle everything that gets thrown up from below them. In the same way, the Suspense component catches any thrown Promises from its children, with the difference that for Suspense we don’t have to make a custom component to act as a boundary, the Suspense component <em>is</em> that boundary, letting us defined the fallback that should be rendered (as well as some additional things, that we’ll touch on later).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zyMcNoP37LkU51V4vdg2LA.gif" /><figcaption>Very simplified visualisation of how Suspense affects the rendering of your component tree, see <a href="https://codesandbox.io/s/pk79xvxq20">https://codesandbox.io/s/pk79xvxq20</a> for interactive demo.</figcaption></figure><p>This whole approach dramatically simplifies the way we will think about application loading states and aligns our mental model as developers more with the one of UX and UI designers.</p><p>Designers usually don’t think about data sources, but more of logical groups and information hierarchy within an interface or application. And you know who else doesn’t care about the source of your data? Users. No one likes an app with thousands of independent loading spinners, some of them only flashing for milliseconds, with the content of the page jumping up and down while the data requests resolve.</p><h3>So why is this so ground breaking?</h3><h4>The problem</h4><p>To understand what the game changer is, let’s take a look at how we currently deal with data fetching in our apps.</p><p>The most primitive approach is by storing all required information in local state, which could look something like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3575aad1b8543022b88c3e07b91ec367/href">https://medium.com/media/3575aad1b8543022b88c3e07b91ec367/href</a></iframe><p>Pretty verbose, huh?</p><p>We fetch the data on mount and store it in local state. Additionally we keep track of errors and loading state through local state as well. Does that look familiar? Even if you are not using state but instead maybe even some kind of abstraction, very likely you still have a lot of those loading ternaries scattered across your app.</p><p>I wouldn’t say this approach is bad per se (it will serve the need for simple use cases, plus we can obviously easily optimise it, e.g. pulling the actual fetch into a separate method for a start), but it doesn’t scale well and the developer experience could definitely be better. To be more specific, I see the following issues with it:</p><ol><li>👎 <strong>Ugly ternaries → bad DX<br></strong> Loading and error states are defined via ternaries in the render, making the code unnecessarily convoluted. We’re not describing one render function, we’re describing three.</li><li>👎 <strong>Boilerplate</strong> <strong>→ bad DX</strong><br>Handling all of this state comes with a lot of boilerplate: triggering the fetch on mount, updating loading state and storing data in state on success or storing the error on failure. We would need to repeat this for every other component that uses external data.</li><li>👎 <strong>Confined data and loading state → bad DX &amp; UX<br></strong>The state is handled and stored within the component, which means we will end up with a million spinners in our app, as well as making multiple unnecessary API calls to the same endpoints if we have different components relying on the same data. This comes back to the point I made earlier, that the mental model of making loading states depend on the data source doesn’t seem right. Through this approach, the loading state is coupled to the data fetching and its component, which limits us to deal with it within this component (or finding cheats to hack around it) instead of being able to handle it in a broader context of the application.</li><li>👎 <strong>Re-fetching data → bad DX</strong><br>Changing ids that i.e. would need to trigger a re-fetch of the data are verbose to implement. We’ll have to do the initial fetch in componentDidMount and additionally to check if the id changes in componentDidUpdate.</li><li>👎 <strong>Flashing spinners → bad UX<br></strong>If the users internet connection is fast enough, showing the loading spinner for just a few milliseconds is even worse than showing nothing at all, making your app feel janky and slower. Perceived performance is key.</li></ol><p>Can you see the pattern? To many it may not come as a surprise, but to me it was never really that clear how hand-in-hand developer and user experience actually go.</p><p>So, having identified the problems, how do we solve them?</p><h4>Introducing Context</h4><p>For a long time Redux has been the go to solution for a lot of these problems. With the <a href="https://reactjs.org/docs/context.html">“new” Context API</a> in React 16 we got another great tool to help us define and expose data on a global level while making it easily accessible in a deeply nested component tree. So for the sake of simplicity we’ll go with the latter here.</p><p>First off, we can easily pull out all the information we previously stored in local state into a context provider, which will allow us to share it with other components. We can also expose a method to fetch data through this provider, so that our components only need trigger this method and read the loaded information via a context consumer. The recently <a href="https://reactjs.org/docs/context.html#classcontexttype">in React 16.6 released </a><a href="https://reactjs.org/docs/context.html#classcontexttype">contextType</a> makes this even more elegant and less verbose.</p><p>The provider also functions as a form of cache, preventing us from hitting the same endpoint multiple times if the data is already there or loading, e.g. triggered by another component.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/924df0c0fe00de762f00d37f078e7ae6/href">https://medium.com/media/924df0c0fe00de762f00d37f078e7ae6/href</a></iframe><p>We could even try to remove the ternary within the component. Let’s say we’d want the loading spinner higher up in the tree, covering more than just this component. Now that we have the loading state in the context, we can simply access it where we want and show a loading spinner there instead, right?</p><p>This is still problematic, since the AsyncData component needs to be rendered in order to trigger the data fetch in the first place. Sure, we could hoist up the fetch as well, somewhere higher up the tree, instead of triggering it in the component, but that doesn’t really solve the problem, it just moves it somewhere else. It’s also bad for code readability and maintainability, suddenly AsyncData relies on some other component doing the data loading for it. This dependency is neither clear nor good. Ideally your components can work as much as possible in isolation, so you can place them anywhere without relying on other components being in specific spots in the component tree around them.</p><p>But at least now we have all the data and loading states in one central place, which is an improvement. And since we’re able to place the provider anywhere, we can consume this information and functionality from wherever we want, meaning that other components can utilise it (no redundant code anymore) and can reuse already loaded data, eliminating unnecessary API calls.</p><p>To put this into perspective, let’s have a look at our initial issues again:</p><ol><li>👎 <strong>Ugly ternaries <br></strong>Nothing changed here, all we can do now is move the ternaries somewhere else, which doesn’t really solve the DX problem.</li><li>👍 <strong>Boilerplate</strong> <br>We removed all the boilerplate that was required before. We only have to trigger the fetch and read the data and loading state from the context, leading to way less repetitive code, which in turn leads to better readability and maintainability of what‘s left.</li><li>👍 <strong>Confined data and loading state <br></strong>We now have a global state that can be accessed anywhere in the application. So we improved the situation significantly, but weren’t able to solve all the issues: loading states are still coupled to the data source, also (even if we find a cheat around these dependencies) if we want to show a loading state depending on multiple components loading their respective information, we still have to explicitly know which sources that are and manually check for all the individual loading states.</li><li>👎 <strong>Re-fetching data</strong> <br>Nothing changed here…</li><li>👎 <strong>Flashing spinners <br></strong>Here neither…</li></ol><p>I think we can all agree that this is still a solid improvement, but it leaves some of the problems unsolved.</p><h4>Suspense to the rescue</h4><p>How can we do better by using Suspense?</p><p>For one, we can get rid of the context, the data handling and caching will be done by a cache provider, which really could be anything. Context, local storage, <a href="https://gist.github.com/julianburr/f19683b791c4ce2aa2509edc530ef77e">a window object</a> (even Redux if you really wanted to), you name it. All this provider does is basically storing the information we request. On every request, it checks first whether the information is already stored. If so, return it. If not, fetch the data, and throw the Promise. Before resolving the Promise, it stores the loaded information in whatever it uses for the cache, so that when React triggers the re-render, everything is available. That’s it. Obviously it gets more complex with more complex use cases, considering things like cache invalidation and SSR, but this is the general gist of it.</p><p>This caching functionality is also one of the reasons why Suspense for data fetching still hasn’t made it into stable React yet. If you want to have a sneak peak, the <strong>experimental</strong> package called <a href="https://github.com/facebook/react/tree/master/packages/react-cache">react-cache</a> is available to play around with. But be aware that in its early stage the API will definitely change and a lot of common use cases are not yet covered.</p><h3>Dan Abramov on Twitter</h3><p>Note: Suspense in 16.6 is meant to be used for code splitting. The data fetching part isn&#39;t ready yet! Don&#39;t use any &quot;cache&quot; package until we document and release it as stable. 🙂 Unless you&#39;re just experimenting.</p><p>All that aside, we can also get rid of all the loading state ternaries. Even more, instead of fetching on component mount and update, suspense works by conditionally fetching in the render, suspending it if the data is not already available through the cache. This might seem like an anti-pattern at first (after all we’ve always been told not to do this), but it makes a lot of sense considering that if the data is in the cache, the provider will simply return it and the render gets executed as normal.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6fbbe7562fc290ba6d3a894792dcce9b/href">https://medium.com/media/6fbbe7562fc290ba6d3a894792dcce9b/href</a></iframe><p>Finally we can place the boundaries and define the fallback component we want to render while the data is fetching. Where? Anywhere we want. As explained before, these boundaries will catch any thrown Promises bubbling up from below them in the tree.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/22e4b341b16f33186384bca60324b34b/href">https://medium.com/media/22e4b341b16f33186384bca60324b34b/href</a></iframe><p>I think this undeniably makes the code a lot cleaner, the logical data flow is now easily readable from top to bottom. But what did it do to our problems?</p><ol><li>❤️ <strong>Ugly ternaries <br></strong>Gone. The fallback rendering is now handled by the boundary, which makes the code easier to follow and feels more intuitive. Loading state has become a UI concern, decoupled from the actual data fetching.</li><li>❤️ <strong>Boilerplate</strong> <br>We improved this one even further, by completely removing the need for life cycle methods to trigger the fetch. Also foreseeing future libraries acting as cache providers, it will only be a matter of switching between those whenever you want to change your storage solution.</li><li>❤️ <strong>Confined data and loading state <br></strong>Solved. Now we have clear boundaries for loading states, which don’t care about where the loading triggers came from or the reasons for them. Whenever any component within the boundary is suspended, the loading state will be rendered, period.</li><li>❤️ <strong>Re-fetching data</strong> <br>Since we (can) pass the source straight in the render method, changes to props that should trigger re-fetching of data will do so automatically, without us needing to do anything. The cache provider takes care of that.</li><li>👎 <strong>Flashing spinners <br></strong>Well, this is still a problem 🤔</li></ol><p>Those are massive improvements, but we still have one problem left … however, now that we’re using Suspense, React has another trick up its sleeve to help us with that one as well.</p><h4>Concurrent mode to finish them off</h4><p>Concurrent mode, or formerly known as Async React, is another upcoming feature that lets React work on more than one task at a time, switching between them depending on defined priorities, effectively allowing it to multi-task. Andrew Clark did <a href="https://www.youtube.com/watch?v=ByBPyMBTzM0">a fantastic talk on it</a> at the last ReactConf, including a great demo of the impact it has for the user. I don’t want to go into all the details here, since this really deserves <a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e">a whole post on its own</a>.</p><p>However, by adding concurrent mode to our app, Suspense receives a new capability that we can control via a prop on the Suspense component. If we now pass in a maxDuration, the boundary will delay showing the loading spinner for that amount of time, preventing spinners from flashing up unnecessarily. It also makes sure the spinner will stay for a minimum amount of time, solving the same issue essentially making sure the user experience is as smooth as possible.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b7f1120431409e0fe72f87fc8c01760d/href">https://medium.com/media/b7f1120431409e0fe72f87fc8c01760d/href</a></iframe><p>To be clear, this will not make the data load any faster, but the user will perceive it as such and the user experience will be dramatically improved.</p><p>Also, concurrent mode is by no means a requirement for Suspense. As we saw before, the general functionality works perfectly fine without it and already solves many problems. Concurrent mode is more the icing on the cake, not absolutely necessary but awesome if there.</p><h3>The takeaway — or a TL;DR if you will</h3><p>Seeing Suspense, it feels like (until now) we had the whole concept of dealing with loading states backwards. They were always tightly coupled to the data source, which usually is tightly coupled to a specific data set or even component.</p><p>Instead, Suspense now allows us to think of loading states as a UI concern. It becomes simple to define areas in your app that will deal with loading states, while at the same time cleaning up the code from verbosity and repetition, a historical baggage we were carrying around for years.</p><p>I also want to give a huge shout out at this stage to the React team, not only for their work on the functionality itself, but even more for letting us developers explore it in its early stages, allowing healthy conversations about API design and most importantly the ecosystem already to pick up, so everything will be in place once Suspense hits the stable release later this year. Thanks! 🎉</p><p><em>PS: I gave a talk about all of this at the </em><a href="https://www.meetup.com/en-AU/reactbris/"><em>ReactBris</em></a><em> meetup. You can find the slides and a small demo application seeing Suspense and Concurrent Mode in action here: </em><a href="https://github.com/julianburr/talk-suspense-game-changer">https://github.com/julianburr/talk-suspense-game-changer</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=37b40fea71ec" width="1" height="1" alt=""><hr><p><a href="https://medium.com/react-in-depth/why-react-suspense-will-be-a-game-changer-37b40fea71ec">Why React Suspense Will Be a Game Changer</a> was originally published in <a href="https://medium.com/react-in-depth">React In Depth</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Practical application of reverse-engineering guidelines and principles]]></title>
            <link>https://medium.com/react-in-depth/practical-application-of-reverse-engineering-guidelines-and-principles-784c004bb657?source=rss----e862e06fcbd9---4</link>
            <guid isPermaLink="false">https://medium.com/p/784c004bb657</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Max Koretskyi]]></dc:creator>
            <pubDate>Sat, 22 Dec 2018 08:22:54 GMT</pubDate>
            <atom:updated>2020-03-20T06:44:05.653Z</atom:updated>
            <content:encoded><![CDATA[<p>Insights into the thought process while reverse-engineering a framework</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*ubfdwakiZkd2NqL8egqQbw.jpeg" /></figure><blockquote><a href="https://medium.com/react-in-depth"><strong><em>ReactInDepth</em></strong></a><strong><em> is moving away from Medium. </em></strong><a href="https://indepth.dev/practical-application-of-reverse-engineering-guidelines-and-principles/"><strong><em>This article</em></strong></a><strong><em>, its updates and more recent articles are hosted on the new platform </em></strong><a href="https://indepth.dev/"><strong><em>inDepth.dev</em></strong></a></blockquote><p>In the article <a href="https://indepth.dev/level-up-your-reverse-engineering-skills/">Level Up Your Reverse Engineering Skills</a> I explained the benefits of reverse-engineering and outlined some guidelines and principles of successful reverse-engineering. If you haven’t read it, I recommend you start from there. This article will demonstrate the application of those guidelines and principles and introduce debugging techniques that I commonly use.</p><p>I was writing this article as I was exploring and debugging the React sources. To get the most value from it, I encourage you to go through a similar discovery process as I did using this article as a guide. If you ever wanted to reverse-engineer something, use this guide as a starting point and join me in this journey of discovery!</p><p>I’m really excited to find out how React works under the hood, like a kid on a Christmas morning 😄. Are you? Let’s get started then!</p><blockquote>Start with acquiring the sources and setting up a sample application</blockquote><p>For reverse-engineering I need both the React sources and a sample React application for debugging. Let’s start with the sources. I go to <a href="https://github.com/facebook/react">github.com/facebook/react</a> and check the “releases” tab:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*qD86Rxa7YiTHH0889n8E_Q.jpeg" /></figure><p>The latest version is 16.4.2:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/925/1*ONayJDai8h4ja8Z5NNY7HQ.jpeg" /></figure><p>Then I clone the project:</p><pre><strong>git clone </strong><a href="https://github.com/facebook/react.git"><strong>https://github.com/facebook/react.git</strong></a></pre><p>search for the version in git tags:</p><pre><strong>$ git tag</strong></pre><pre>…<br>v16.4.0<br>v16.4.0-alpha.16.4.0-alpha.7926752<br>v16.4.0-alpha.5a25959<br>v16.4.0-alpha.94a255d<br>v16.4.1<br><strong>v16.4.2</strong></pre><p>and checkout the version I need (v16.4.2):</p><pre><strong>$ git checkout tags/v16.4.2</strong></pre><pre>Checking out files: 100% (728/728), done.<br>Previous HEAD position was 7d9b4ba35 Update bundle sizes for 16.1.0 release<br>HEAD is now at 54adb2674 16.4.2</pre><p>Now I need to set up a project with the same version of React. I recommend using the simplest setup possible — <a href="https://reactjs.org/docs/add-react-to-a-website.html#add-react-in-one-minute">HTML page with the library</a>. And it’s awesome that React is bundled to make this setup possible.</p><p>Once I download the project, I need to update the version of React to <strong>16.4.2</strong>. I can specify the version I need in the unpckg bundle inside the index.html:</p><pre>&lt;script src=&quot;https://unpkg.com/<strong>react@16.4.2</strong>/umd/react.development.js&quot; crossorigin&gt;&lt;/script&gt;<br>&lt;script src=&quot;https://unpkg.com/<strong>react-dom@16.4.2</strong>/umd/react-dom.development.js&quot; crossorigin&gt;&lt;/script&gt;</pre><p>Okay, just to test that it works, I run the HTTP server inside the folder with index.html:</p><pre><strong>$ http-server .</strong></pre><pre>Starting up http-server, serving .<br>Available on:<br>  <a href="http://192.168.0.4:8080/">http://192.168.0.4:8080</a><br>  <a href="http://127.0.0.1:8080/">http://127.0.0.1:8080</a><br>Hit CTRL-C to stop the server</pre><p>Everything’s fine, the server is started on port 8080. Nice.</p><blockquote>Identify the part of the technology to focus on</blockquote><p>Okay, now I need to figure out the place where to start the process of reverse-engineering. Right now I’m wondering how change detection works in React. So that is <strong>my goal </strong>to start with.</p><p>However, it still doesn’t tell me where to put the debugger statement or what files to look for in the sources. To find out that I’m going to use my knowledge of the modern change detection process</p><blockquote>Know common design patterns and general architectural concepts</blockquote><p>I know that change detection is about synchronizing changes from a component instance to DOM nodes. In React we initiate the change detection process by calling setState. So I can start from there. However, since I learned from the docs that it’s an asynchronous call, I don’t think it’ll lead me directly to the relevant parts. So, instead, I’ll focus on identifying where React stores references to the created DOM nodes. Once I know that, I think I can track down where these DOM nodes are accessed and work forward from there. It seems that this path might get me closer to the end goal of understanding change detection: <strong>so I’ll focus on DOM nodes</strong>.</p><h4>DOM nodes to look for</h4><p>Before I can figure out where DOM nodes are stored, I need to know what DOM nodes will be created for the component. Here is how a React component looks like in my simple application:</p><pre><strong>class LikeButton extends React.Component {</strong><br>  constructor(props) {<br>    super(props);<br>    this.state = { liked: false };<em><br>  </em>}</pre><pre><strong>  render() {<br></strong>    if (this.state.liked) {<br>      return &#39;You liked this.&#39;;<br>    }</pre><pre><strong>    return e(<br>      &#39;button&#39;,<br>      { onClick: () =&gt; this.setState({ liked: true }) },<br>      &#39;Like&#39;<br>    );<br>  }</strong><br><strong>}</strong></pre><p>I’m looking at the render function responsible for returning a template for a component. Here the e is an alias for React.createElement:</p><pre>const e = React.createElement;</pre><p>In Angular, a template for a component is defined using HTML. In React however, the template is defined by composing calls to the createElement function. So, I need to figure out what HTML will be produced by the following statement:</p><pre>return e(<br>    &#39;button&#39;,<br>    {onClick: () =&gt; this.setState({liked: true})},<br>    &#39;Like&#39;<br>);</pre><p>Well, since it’s a call to the createElement function I can explore the function’s implementation. But first, I need to find that function in the sources. To do that I open sources in WebStorm and use the IDE’s Search Everywhere functionality:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/482/1*KYFF1P8BDWIZc_50Fq2_wQ.jpeg" /></figure><p>The first two results seem promising. I’m going to use signatures to figure out which function I need. Here is the signature for the function in the react-dom package:</p><pre>export function createElement(<br>  type: string,<br>  props: Object,<br>  rootContainerElement: Element | Document,<br>  parentNamespace: string,<br>): Element { ... }</pre><p>And the signature for the function in the react package:</p><pre>export function createElement(type, config, children) { ... }</pre><p>So, which one do I need?</p><blockquote>Think like a scientist</blockquote><p>In <a href="https://blog.angularindepth.com/level-up-your-reverse-engineering-skills-8f910ae10630">the first article</a> I defined the basic steps for the scientific approach:</p><ol><li>Make an observation and form a hypothesis.</li><li>Make a prediction based on the hypothesis.</li><li>Test the prediction.</li></ol><p>So let’s now use this approach. <strong>Observing </strong>the parameters list, I <strong>assume</strong> the first function is used in the render method of the component. It’s also inside the react-dom package which adds credibility to my assumption. So that is my <strong>hypothesis </strong>— the function createElement from the react-dom package is used inside the render method. Hence, I <strong>predict </strong>that this function will be executed when React calls the render method on the component. I now need to <strong>test the prediction</strong>. To do that, I put a debugger statement before the call to createElement, run my example and when the execution is paused I step into the e function call to see where I’ll end up:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-xKJX6Jl5Nd2miznXnVk_w.jpeg" /></figure><p>Interestingly, I end up inside the createElementWithValidation function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/839/1*K7flgnGpPFANYr5ZlpjUjw.jpeg" /></figure><p>Not the function I expected. Based on the function name, I guess it’s just a wrapper around createElement. I assume that this function has the call to the createElement function inside. So I look up this function in the sources:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/483/1*ExE1m6mUEvT3K-M9vjet-g.jpeg" /></figure><p>and explore its implementation. Indeed, I see the call to the createElement inside:</p><pre>export function createElementWithValidation(type, props, children) {<br>  const validType = isValidElementType(type);<br>  ...<br><br><strong>  const element = createElement.apply(this, arguments);</strong></pre><p>At this point I can either continue exploring the sources relying on WebStorm’s ability to figure out the location of the referenced createElement function or go back to debugging. React is written in JavaScript and for projects written in JS I normally prefer debugging over exploring sources using an IDE’s reference resolution mechanism. It’s a different story with TypeScript because it’s mostly strongly typed. But in this particular case React uses ES modules for importing references:</p><pre><strong>import</strong> {isValidElement, createElement, ...} <strong>from </strong>&#39;./ReactElement&#39;;</pre><p>which provides a reliable way for an IDE to resolve the location of the references. So I’ll stick to the sources for now. I control-click on the createElement and WebStorm navigates me to the function in the react/src/ReactElement.js:</p><pre>export function createElement(type, config, children) { ... }</pre><p>And it’s <strong>not </strong>the function I assumed would be called! <strong>My assumption was wrong</strong>. That happens all the time, don’t get discouraged by getting your hypothesis wrong.</p><p>Actually, I’m still a bit suspicious about my wrong assumption. So I’m going to test it again using the debugger. Switching between debugging and exploring implementations in the sources is very common during reverse-engineering.</p><p>Remember, we’ve ended up in the createElementWithValidation function:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/839/1*K7flgnGpPFANYr5ZlpjUjw.jpeg" /></figure><p>So scroll a bit lower and put a breakpoint at the line of thecreateElement function call and use the Continue to here functionality of the debugger:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/858/1*0_HtgxOntAArUG2BYp-nNw.jpeg" /></figure><p>I then step into the function call and end up inside the createElement:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/844/1*2L6VUkomKTqNmTlh1JbpzQ.jpeg" /></figure><p>Okay, it’s the same function I arrived at using IDE’s resolution process. Now that I know which function is used in the render function, I can figure out the HTML. I just need to match the parameters in the function’s signature and the function’s call:</p><pre>// signature<br>function createElement(type, config, children) { ... }</pre><pre>// actual call<br>return e(<br>    &#39;button&#39;,<br>    {onClick: () =&gt; this.setState({liked: true})},<br>    &#39;Like&#39;<br>);</pre><p>Now I’m using my knowledge of how a browser DOM works to come up with a template. There will be a bunch of <strong>hypotheses </strong>here. I assume that the type parameter refers to the tag name of a DOM node. The config specifies a bunch of event handlers and thechildren parameter defines child nodes. So I <strong>predict </strong>that based on the information supplied to the function, React will create DOM nodes corresponding to the following template:</p><pre>&lt;button (click)=&quot;() =&gt; this.setState({ liked: true })&quot;&gt;<br>    Like<br>&lt;/button&gt;</pre><p>These nodes will be: a button element with one click event binding and a child text node with the value Like. So that is my prediction that I need to validate. To do that I need to see what DOM nodes will be created by React and compare them to the template I came up with.</p><blockquote>Notice how the <strong>knowledge about underlying platform</strong> is required to come up with the template. You have to know about different types of DOM nodes.</blockquote><p>If I’m lucky, these DOM nodes will be created inside the function createElement. Since I have an application paused inside the createElement function, I’ll continue with debugging to explore the function’s body. I could do that from the sources, but I usually prefer debugging over the sources, mostly because I don’t need to rely on IDE’s ability to resolve references and can immediately observe the values that variables hold.</p><p>So I quickly skim through the function body and stumble upon the call to ReactElement as a return statement:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/849/1*R1Q4s-wsmAChK0KKXxs2tw.jpeg" /></figure><p>Now it’s time to switch to the sources and explore the function ReactElement there:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/483/1*e_tvJSd3P9N-O9bofZPP5Q.jpeg" /></figure><p>I want to see if it creates DOM nodes. Well, it doesn’t. As I can see, this function just creates a data structure called ReactElement. I’m instantly curios how this data structure is used in React. Interestingly, it has the type property:</p><pre>const element = {<br>  <em>// This tag allows us to uniquely identify this as a React Element<br>  </em>$$typeof: REACT_ELEMENT_TYPE,</pre><pre>  <em>// Built-in properties that belong on the element<br>  </em><strong>type: type,</strong><br>  key: key,<br>  ...</pre><pre>};</pre><p>So I’m wondering if the value for this property will be the string button. Since my application is paused at the call to the ReactElement function:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/849/1*R1Q4s-wsmAChK0KKXxs2tw.jpeg" /></figure><p>I can step into the function call to find out:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/603/1*ILXfnu6VbHaXNIDuMBnbMw.jpeg" /></figure><p>Well, the first call is not the string button, but a class reference to the LikeButton component. I’m going to remember that and get back to it later. I assume that the button string should come in one of the next calls. I don’t know how many more calls there’s going to be, but I know that I can expect the button string to come only after the render function has started executing. So here is a neat trick I can use. I disable the breakpoint in the createElement function until I hit the debugger statement in the render function:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*pwwhqEolMyfNVpEiqvNJeg.jpeg" /></figure><p>Once the breakpoint is disabled I resume execution:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/572/1*jW0fPqQVa9xqUf8T65ETmA.jpeg" /></figure><p>Until I hit the debugger statement in the render function:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/571/1*nzLL2x6SNI5J0gRx7QAopA.jpeg" /></figure><p>I then navigate to the disabled breakpoint</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/621/1*lby_WUf_94aWfES1zmQGaw.jpeg" /></figure><p>and enable it</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/519/1*hbfeUlW3RZCREuH271L9Tg.jpeg" /></figure><p>Okay, so now I resume execution and inspect the value of the type parameter:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/613/1*nwKz3oT9740pbWI4TJT17g.jpeg" /></figure><p>Great! As I guessed the element we’re creating is the button.</p><p>The comment that describes the function states that it used to create a React Element. So I guess the data structure that acts as a proxy for a DOM node in React is called ReactElement. Interesting. There’s also a link to the documentation on React Elements so I’ll need to get back to it and get familiar with the docs. But, I’ll do that a bit later when I get to the investigation of the role React Elements play in the framework. For now I need to stick to <strong>my task of validating the prediction</strong> about the DOM nodes that React will create for the component.</p><p>I continue debugging and when I exit the render function I see the following code:</p><pre>{<br>    ReactDebugCurrentFiber.setCurrentPhase(&#39;render&#39;);<br>    <strong>nextChildren = instance.render();</strong><br>    if (debugRenderPhaseSideEffects || ...) {<br>        instance.render();<br>    }<br>    ReactDebugCurrentFiber.setCurrentPhase(null);<br>}</pre><p>I observe the surrounding code and see the word <strong>Fiber</strong> everywhere. I have no idea what it is, so I’ll google it. The search turns up numerous results. I’ve quickly scanned some of them and it seems that Fiber is the new engine. I’ll definitely need to read more about it.</p><blockquote>Allow yourself some time to think about what you’ve found</blockquote><p>So I’m going to pause now and think about what I’ve discovered so far. For each createElement function call, React creates a data structure called ReactElement. So, I want to add this to my notes:</p><pre>createElement(type) -&gt; ReactElement.type</pre><p>I’ve seen two calls to the createElement function — the first one with the type of the LikeButton class reference and the second one with the string button. So, I assume that we can have two types of React Elements: component class references and DOM nodes types.</p><p>I still haven’t found where the DOM node is created. <strong>It’s important to find that place to validate the hypothesis about types of DOM nodes created.</strong></p><blockquote>Use the Call Stack to construct the application flow</blockquote><p>At this point I want to take a look at the <strong>Call Stack</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/682/1*7OKzTixeRvGVtHWfg7N3yQ.jpeg" /></figure><p>By clicking through the functions in the <strong>Call Stack</strong> I infer that React is going through some work loop and executes pieces of work bit by bit. I suppose that one such piece of work could be creating a DOM node, but I’ll need to work through the multiple iterations of the loop to find out that. Debugging loops is always time consuming, and if a loop is asynchronous, which I imagine is the case here, the complexity of debugging rises drastically.</p><blockquote>Have a good grasp on the underlying platform</blockquote><p>So, instead, I’ll use my knowledge of the native DOM API and try to find the createElement native DOM API call in the sources. This method is called on the document to create a DOM node. I don’t expect React to use document directly, but rather a platform independent wrapper. So I’ll be searching for .createElement with the dot before the name omitting the document.</p><p>I’ll first do a search inside packages/react/src. There seems to be nothing there besides tests. Okay, maybe there’s something in a different package. So I’ll do a search through all packages excluding test files:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/1*X0FIsb560ymBKf7eqBpqWA.jpeg" /></figure><p>I know<strong> </strong>that createElement should be called on document, and I see something promising:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*0c0R6fwZ6A8YqG9X05kXEQ.jpeg" /></figure><p>Great. Similar to how I did with the createElement function, I’ll use debugging to verify if the function I’ve found is used to create DOM nodes. I expect it to be called to create the button HTML element. To check it, I need to find this code in the sources loaded to the browser and add a breakpoint there.</p><blockquote>Have a good command of debugging tools</blockquote><p>So, I do a search in the sources tab of Chrome’s Dev Tools using Ctrl+Shift+F and look for the parent.ownerDocument.createElement(parent.tagName) line. This is what I get:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/907/1*4DfNcQ7kfqkgb5ddOGD1-A.jpeg" /></figure><p>I double click it and end up in the corresponding file. So, I then add a breakpoint and reload my application. <strong>Nothing. </strong>The breakpoint is not hit so I guess it’s not the method I’m looking for. Again, I got it wrong.</p><blockquote>Approach the task from different angles</blockquote><p>But I’ll try something else here. Here is a technique I use quite often. I replace methods on objects with methods that wrap around original functionality and add the debugger statement: inside. This is a variation of the decorator pattern. When someone calls the decorated method on an object anywhere in the application, the debugger statement is hit and I can see in the Call Stack where the call is made from.</p><p>I’ll use this technique on the document object and decorate the createElement method. Usually, it’s important to decorate the method as early as possible in the application. In my case I know that the button DOM node won’t be created until after the render method is called on the component instance, so I can decorate the document at this point.</p><p>So, as soon as the application is paused in the render method, I decorate the createElement method by executing a few statements in the console:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/740/1*h9Uo6Su5-Y1LcVRfox4UqA.jpeg" /></figure><p>When I resume the execution it is then paused exactly at my debugger statement:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/778/1*N5TS6T6q50d8C-QvPJcLvQ.jpeg" /></figure><p>Now all I need to do is inspect the <strong>Call Stack</strong>. I first check the previous function call:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1007/1*yIKg_d5uF1RLk3gfbv0aIw.jpeg" /></figure><p>There are a couple of things to notice here. One thing is that the function that creates DOM nodes is called createElement$1 in the code. The other thing is that React references document as ownerDocument. This is useful information and I’ll use it when I’ll be searching for other method calls on the document.</p><p>I’ll now take a look at the createInstance function call:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*YkdxSCuY0kthxYmfsMIeqw.jpeg" /></figure><p>Cool, here the function name is createElement. And it creates the button DOM node. I don’t know why the previous call adds $1 to the function name, but it’s not important at this point. <strong>Perfect, I’ve found the function that creates DOM nodes!</strong></p><p>Now I need to find it in the sources. I do a full search in WebStorm:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/482/1*etk-Iu3bC-cR-IKvxi8E4w.jpeg" /></figure><p>And see the familiar list again. That’s the list we started from. The first time I saw it I assumed that the function from the react-dom package will be executed inside the render function:</p><pre>return createElement(<br>    &#39;button&#39;,<br>    {onClick: () =&gt; this.setState({liked: true})},<br>    &#39;Like&#39;<br>);</pre><p>But it was the second function that was called which created a React Element.</p><blockquote>So I can conclude now that the function from the react-dom package creates DOM nodes, while the function from the react package creates React Elements.</blockquote><p>That’s important information! I can use it to infer that for functions related to DOM, I should be looking inside the react-dom package. On the other hand the react package probably contains platform independent logic. I can make such an inference because I know that React is a multi platform framework. I also know how Angular packages are structured, that they have @angular/core and @angular/platform-browser which seem to be similar to React.</p><p>Now I want to spend some time exploring the file where the function createElement is placed so I can start learning the code base. The filename with the createElement function is called ReactDomFiberComponent.js. There are many functions in the file that perform DOM operations, for example: createElement, createTextNode and updateDOMProperties. <strong>I’m so happy I’ve found it!</strong> Now I have a place to look for functions to put the debugger in when I need to intercept a DOM operation.</p><p>Now I’m finally ready to validate my predication that the following call</p><pre>return createElement(<br>    &#39;button&#39;,<br>    {onClick: () =&gt; this.setState({liked: true})},<br>    &#39;Like&#39;<br>);</pre><p>will create one button element node, one text node with the value Like and add one event listener to the button element.</p><p>I know which functions create element and text nodes, but I don’t know which function adds an event listener. I’ll do a search in the react-dom package and find the following functions:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/915/1*9dwdPl8VbgLtGcvcgnUxYA.jpeg" /></figure><p>It must be either the first or the second one.</p><p>So, to validate the prediction, I add the debugger statements to functions createElement, createTextNode and addEventBubbleListener and addEventCaptureListener. When I reload the application I hit breakpoints in the createElement and addEventBubbleListener functions. The click event is bubbling, so it makes sense that the bubble variant of the addEventListener was executed. However, the function createText node wasn’t executed. I wonder now how the text node Like was created. Maybe it was created inside the createElement function?</p><p>To find that out, I’m going to continue stepping over the calls and check the childNodes property. This is where my knowledge of the underlying platform comes in handy. This technique will allow me to quickly move through the calls and identify the function that added the child node.</p><p>So, the first function I exit is createElement. I check the property:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/594/1*F06CV5Vzt0NV4kn7HhfTTw.jpeg" /></figure><p>Nope, it’s 0. It means that child node wasn’t created by the createElement function. I then step over precacheFiberNode$1 and updateFiberProps$1 checking the property after each function. The child text node is not added. I continue debugging and end up in the completeWork function:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/819/1*eoKrDZNOIqdaAeudFvfq8g.jpeg" /></figure><p>The variable _instance holds the reference to the created DOM node. I also check the workInProgress variable which references FiberNode:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/884/1*UoulQNzfQLxqCP2YmD_HOw.jpeg" /></figure><p>Based on the variable name and a little info I read on Fiber, I assume the FiberNode represents a chunk of work to do in the new Fiber architecture.</p><p>Now I step over the appendAllChildren function call and check the childNodes again:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/821/1*n0YK137vx_T61dkG8kUL2g.jpeg" /></figure><p>Nope, still 0. That means that the child was not added in the appendAllChildren and at this point I don’t need to dive into it. Now I repeat the same with the call to finalizeInitialChildren. Step over and check:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/1*X0i5LlytglKlR2IRoU7jqQ.jpeg" /></figure><p>Great, now we have it. I’ve pinpointed the function finalizeInitialChildren that created the child node. By continuing debugging and using the approach of checking the chidlNodes value, I’ve found the code that adds the text node inside the setInitialDOMProperties function:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/824/1*CQ7E3Tv9Z4E7aPHiae0UFA.jpeg" /></figure><p>When I step into the setTextContent function I see how the node was added:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/476/1*EbqAx-3CDSMU7FOLuL5cSw.jpeg" /></figure><p><strong>Finally, I’ve verified my prediction on what types of DOM nodes will be created!</strong> Take a moment to appreciate how much we’ve learnt along the way: functions that create React Elements and DOM nodes, their locations, difference between packages, new Fiber architecture. Amazing, isn’t it?</p><blockquote>A word about luck</blockquote><p>I talked about luck and the role it plays in the process of reverse-engineering in <a href="https://blog.angularindepth.com/level-up-your-reverse-engineering-skills-8f910ae10630">my previous article</a>. Well, here is a great demonstration. I started debugging with the goal to find out where React stores DOM nodes. Incidentally, if I just lower my gaze under the finalizeInitialChildren function call I see the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/802/1*0v0ke_4X5bLttBWawHihXg.jpeg" /></figure><p>The button DOM element created above is attached to the workInProgress fiber node. <strong>So</strong> <strong>DOM nodes are attached to Fiber Nodes. </strong>That’s where React stores references to DOM nodes.</p><p>Of course, that’s just a start. There’s a very long of road of discovery ahead.</p><p>At this point I simply know that the created DOM node and its children are attached to the FiberNode’s stateNode property. Based on my knowledge of how Angular stores DOM elements, I assume that there should be some kind of data structure corresponding to components that will hold the references to the DOM. Could the Fiber Node, which is a piece of work, be that kind of data structure? It’s possible, but I haven’t seen anything like that. Now I need to imagine how I would design that kind of system if that were the case? For that to work, I’d need to store Fiber Nodes somewhere and then iterate over them when the DOM needs an update.</p><p>I’ll need to take a look at the Fiber Node class and its type. I’ll need to figure out where Fiber nodes are stored and how they are processed. So many questions to find answers to. But I’m excited!</p><h4>Thanks for reading! If you liked this article, hit that clap button below 👏. It means a lot to me and it helps other people see the story.</h4><h4>For more insights follow me on <a href="https://twitter.com/maxkoretskyi">Twitter</a> and on <a href="https://medium.com/@maxim.koretskyi">Medium</a>.</h4><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=784c004bb657" width="1" height="1" alt=""><hr><p><a href="https://medium.com/react-in-depth/practical-application-of-reverse-engineering-guidelines-and-principles-784c004bb657">Practical application of reverse-engineering guidelines and principles</a> was originally published in <a href="https://medium.com/react-in-depth">React In Depth</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The how and why on React’s usage of linked list in Fiber]]></title>
            <link>https://medium.com/react-in-depth/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7?source=rss----e862e06fcbd9---4</link>
            <guid isPermaLink="false">https://medium.com/p/67f1014d0eb7</guid>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[algorithms]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Max Koretskyi]]></dc:creator>
            <pubDate>Thu, 13 Dec 2018 14:21:30 GMT</pubDate>
            <atom:updated>2020-03-07T11:22:35.767Z</atom:updated>
            <content:encoded><![CDATA[<h3>The how and why on React’s usage of linked list in Fiber to walk the component’s tree</h3><h4>The main algorithm of the work loop in React’s reconciler</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/984/1*d8GcL9UNG0w9n_WW5TCWRw.png" /><figcaption>Work loop representation from <a href="https://www.youtube.com/watch?v=ZCuYPiUIONs">an amazing talk by Lin Clark</a> at ReactConf 2017</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*7CImQFZPe816uJN9FPSWxQ.png" /></figure><p><a href="https://medium.com/react-in-depth"><strong>ReactInDepth</strong></a><strong> is moving away from Medium. </strong><a href="https://indepth.dev/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-to-walk-the-components-tree/"><strong>This article</strong></a><strong>, its updates and more recent articles are hosted on the new platform </strong><a href="https://indepth.dev/"><strong>inDepth.dev</strong></a></p><p>To educate myself and the community, I spend a lot of time <a href="https://blog.angularindepth.com/practical-application-of-reverse-engineering-guidelines-and-principles-784c004bb657">reverse-engineering web technologies</a> and writing about my findings. In the last year, I’ve focused mostly on Angular sources which resulted in the biggest Angular publication on the web — <a href="https://blog.angularindepth.com/">Angular-In-Depth</a>. <strong>Now the time has come to dive deep into React</strong>. <a href="https://medium.freecodecamp.org/what-every-front-end-developer-should-know-about-change-detection-in-angular-and-react-508f83f58c6a">Change detection</a> has become the main area of my expertise in Angular, and with some patience and <em>a lot of debugging,</em> I hope to soon achieve that level in React.</p><p>In React, the mechanism of change detection is often referred to as reconciliation or rendering, and Fiber is its newest implementation. Due to the underlying architecture, it provides capabilities to implement many interesting features like performing non-blocking rendering, applying updates based on the priority and pre-rendering content in the background. These features are referred to as <strong>time-slicing</strong> in the <a href="https://twitter.com/acdlite/status/1056612147432574976">Concurrent React philosophy</a>.</p><p>Besides solving real problems of application developers, <strong>the internal implementation of these mechanisms has a wide appeal from the engineering perspective. There’s such a wealth of knowledge in the sources that will help us grow as developers.</strong></p><p>If you Google “React Fiber” today you’re going to see quite a lot articles in the search results. All of them, though, except for the <a href="https://github.com/acdlite/react-fiber-architecture">notes by Andrew Clark</a> are pretty high-level explanations. In this article, I’ll refer to this resource and<strong> provide an elaborate explanation for some particularly important concepts in Fiber</strong>. Once we’ve finished, you’ll have enough knowledge to understand the work loop representation from <a href="https://www.youtube.com/watch?v=ZCuYPiUIONs">a very good talk by Lin Clark</a> at ReactConf 2017. <em>That’s the one talk you need to see.</em> But it’ll make a lot more sense to you after you’ve spent a little time in the sources.</p><p><a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e"><strong>This post opens a series on React’s Fiber internals.</strong></a> I’m about 70% through understanding the internal details of the implementation and have three more articles on reconciliation and rendering mechanism in the works.</p><blockquote>I work as a developer advocate at <a href="https://react-grid.ag-grid.com/?utm_source=medium&amp;utm_medium=blog&amp;utm_campaign=reactcustom"><strong>ag-Grid</strong></a>. If you’re curious to learn about data grids or looking for the ultimate react data grid solution, give it a try with the guide “<a href="https://blog.ag-grid.com/react-get-started-with-react-grid-in-5-minutes/?utm_source=medium&amp;utm_medium=blog&amp;utm_campaign=getstartedangular"><strong>Get started with React grid in 5 minutes</strong></a>”. I’m happy to answer any questions you may have. <a href="https://twitter.com/maxkoretskyi"><strong>And follow me to stay tuned</strong></a><strong>!</strong></blockquote><p>Let’s get started!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*7CImQFZPe816uJN9FPSWxQ.png" /></figure><h3>Setting the background</h3><p>Fiber’s architecture has two major phases: reconciliation/render and commit. In the source code the reconciliation phase is mostly referred to as the “render phase”. This is the phase when React walks the tree of components and:</p><ul><li>updates state and props,</li><li>calls lifecycle hooks,</li><li>retrieves the children from the component,</li><li>compares them to the previous children,</li><li>and figures out the DOM updates that need to be performed.</li></ul><p><strong>All these activities are referred to as work inside Fiber</strong>. The type of work that needs to be done depends on the type of the React Element. For example, for a Class Component React needs to instantiate a class, while it doesn&#39;t do it for a Functional Component. If interested, <a href="https://github.com/facebook/react/blob/340bfd9393e8173adca5380e6587e1ea1a23cefa/packages/shared/ReactWorkTags.js#L29-L28">here</a> you can see all types of work targets in Fiber. These activities are exactly what Andrew talks about here:</p><blockquote>When dealing with UIs, the problem is that if <strong>too much work is executed all at once</strong>, it can cause animations to drop frames…</blockquote><p>Now what about that ‘<em>all at once’</em> part? Well, basically, if React is going to walk the entire tree of components <strong>synchronously</strong> and perform work for each component, it may run over 16 ms available for an application code to execute its logic. And this will cause frames to drop causing stuttering visual effects.</p><p>So this can be helped?</p><blockquote>Newer browsers (and React Native) implement APIs that help address this exact problem…</blockquote><p>The new API he talks about is the <a href="https://developers.google.com/web/updates/2015/08/using-requestidlecallback">requestIdleCallback</a> global function that can be used to queue a function to be called during a browser’s idle periods. Here’s how you would use it by itself:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/77bae99105ef86627c132b948da52f10/href">https://medium.com/media/77bae99105ef86627c132b948da52f10/href</a></iframe><p>If I now open the console and execute the code above, Chrome logs 49.9 false. It basically tells me that I have 49.9 ms to do whatever work I need to do and I haven’t yet used up all allotted time, otherwise the deadline.didTimeout would be true. Keep in mind that timeRemaining can change as soon as a browser gets some work to do, so it should be constantly checked.</p><blockquote><strong>requestIdleCallback</strong> is actually a bit too restrictive and <a href="https://github.com/facebook/react/issues/13206#issuecomment-418923831">is not executed often enough</a> to implement smooth UI rendering, so React team <a href="https://github.com/facebook/react/blob/eeb817785c771362416fd87ea7d2a1a32dde9842/packages/scheduler/src/Scheduler.js#L212-L222">had to implement their own version</a>.</blockquote><p>Now if we put all the activities Reacts performs on a component into the function performWork, and use requestIdleCallback to schedule the work, our code could look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3b5a96a981a50457cce57c868a7a4ba8/href">https://medium.com/media/3b5a96a981a50457cce57c868a7a4ba8/href</a></iframe><p>We perform the work on one component and then return the reference to the next component to process. This would work, if not for one thing. You can’t process the entire tree of components synchronously, as in the p<a href="https://reactjs.org/docs/codebase-overview.html#stack-reconciler">revious implementation of the reconciliation algorithm</a>. And that’s the problem Andrew talks about here:</p><blockquote>in order to use those APIs, you need a way to break rendering work into incremental units</blockquote><p>So to solve this problem, React had to re-implement the algorithm for walking the tree <strong>from the synchronous recursive model that relied on the built-in stack to an asynchronous model with linked list and pointers.</strong> And that’s what Andrew writes about here:</p><blockquote>If you rely only on the [built-in] call stack, it will keep doing work until the stack is empty…Wouldn’t it be great if we could interrupt the call stack at will and manipulate stack frames manually? That’s the purpose of React Fiber. <strong>Fiber is re-implementation of the stack, specialized for React components</strong>. You can think of a single fiber as a virtual stack frame.</blockquote><p>And that’s what I’m going to explain now.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*7CImQFZPe816uJN9FPSWxQ.png" /></figure><h4>A word about the stack</h4><p>I assume you’re all familiar with the notion of a call stack. This is what you see in your browser’s debugging tools if you pause code at a breakpoint. Here are a few relevant quotes and diagrams <a href="https://en.wikipedia.org/wiki/Call_stack?fbclid=IwAR06VWEQnwoEawg0NsoR8loBJwIbmPWsXXKqbAuOFBjkawHThK7zlIBsJ_U#Structure">from Wikipedia</a>:</p><blockquote>In computer science, a <strong>call stack</strong> is a stack data structure that stores information about the active subroutines of a computer program… the main reason for having call stack is <strong>to keep track of the point</strong> to which each active subroutine should return control when it finishes executing… A <strong>call stack</strong> is composed of <strong>stack frames</strong>… Each stack frame corresponds to a call to a subroutine which has not yet terminated with a <strong>return</strong>. For example, if a subroutine named DrawLine is currently running, having been called by a subroutine DrawSquare, the top part of the call stack might be laid out like in the adjacent picture.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/513/1*WqEscsoRHItF0p4fZjHfsA.png" /></figure><h4>Why is the stack relevant to React?</h4><p>As we defined in the first part of the article, Reacts walks the components tree during the reconciliation/render phase and performs some work for components. The previous implementation of the reconciler used the synchronous recursive model that relied on the built-in stack to walk the tree. <a href="https://reactjs.org/docs/reconciliation.html#recursing-on-children">The official doc on reconciliation</a> describe this process and talk a lot about recursion:</p><blockquote>By default, when recursing on the children of a DOM node, React just iterates over both lists of children at the same time and generates a mutation whenever there’s a difference.</blockquote><p>If you think about it, <strong>each recursive call adds a frame to the stack. And it does so synchronously</strong>. Suppose we have the following tree of components:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/484/1*TYWa1WAZ9iLip-rwBNPGEQ.png" /></figure><p>Represented as objects with the render function. You can think of them as instances of components:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bc6c7523432b413bba1e472c8aa3f88f/href">https://medium.com/media/bc6c7523432b413bba1e472c8aa3f88f/href</a></iframe><p>React needs to iterate the tree and perform work for each component. To simplify, the work to do is to log the name of the current component and retrieve its children. Here’s how we do it with recursion.</p><h4>Recursive traversal</h4><p>The main function that iterates over the tree is called walk in the implementation below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/039fab4e1fdd9508fbcc8649adb8d550/href">https://medium.com/media/039fab4e1fdd9508fbcc8649adb8d550/href</a></iframe><p>Here’s the output we’re getting:</p><pre><strong>a1, b1, b2, c1, d1, d2, b3, c2</strong></pre><p>If you don’t feel confident with recursions, check out <a href="https://medium.freecodecamp.org/learn-recursion-in-10-minutes-e3262ac08a1">my in-depth article on recursion</a>.</p><p>A recursive approach is intuitive and well-suited for walking the trees. But as we discovered, it has limitations. The biggest one is that we can’t break the work into incremental units. We can’t pause the work at a particular component and resume it later. With this approach React just keeps iterating until it processed all components and the stack is empty.</p><p><strong>So how does React implement the algorithm to walk the tree without recursion? It uses a singly linked list tree traversal algorithm. It makes it possible to pause the traversal and stop the stack from growing.</strong></p><h3>Linked list traversal</h3><p>I was lucky to find the gist of the algorithm outlined by Sebastian Markbåge <a href="https://github.com/facebook/react/issues/7942#issue-182373497">here</a>. To implement the algorithm, we need to have a data structure with 3 fields:</p><ul><li>child — reference to the first child</li><li>sibling — reference to the first sibling</li><li>return — reference to the parent</li></ul><p>In the context of the new reconciliation algorithm in React, the data structure with these fields is called Fiber. Under the hood it’s the representation of a React Element that keeps a queue of work to do. More on that in my next articles.</p><p>The following diagram demonstrates the hierarchy of objects linked through the linked list and the types of connections between them:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/536/1*7dsyUaUpKbFG7EoNR9Cu2w.png" /></figure><p>So let’s first define our custom node constructor:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1af0fed9ba07c1f9f463411034908751/href">https://medium.com/media/1af0fed9ba07c1f9f463411034908751/href</a></iframe><p>And the function that takes an array of nodes and links them together. We’re going to use it to link children returned by the render method:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/db37ab824ade272737072e3108e474b1/href">https://medium.com/media/db37ab824ade272737072e3108e474b1/href</a></iframe><p>The function iterates over the array of nodes starting from the last one and links them together in a singly linked list. It returns the reference to the first sibling in the list. Here is a simple demo of how it works:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9be1467620cf29abdb1bf76222b60397/href">https://medium.com/media/9be1467620cf29abdb1bf76222b60397/href</a></iframe><p>We’ll also implement a helper function that performs some work for a node. In our case, it’s going to log the name of a component. But besides that it also retrieves the children of a component and links them together:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d8a53b55f2f3f0266f58ef3ea73725e2/href">https://medium.com/media/d8a53b55f2f3f0266f58ef3ea73725e2/href</a></iframe><p>Okay, now we’re ready to implement the main traversal algorithm. It’s a parent first, depth-first implementation. Here is the code with useful comments:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d81e68240f07d87d58971c8a04b48637/href">https://medium.com/media/d81e68240f07d87d58971c8a04b48637/href</a></iframe><p>Although the implementation is not particularly difficult to understand, you may need to play with it a little to grok it. <a href="https://stackblitz.com/edit/js-tle1wr">Do it here</a>. The idea is that we keep the reference to the current node and re-assign it while descending the tree until we hit the end of the branch. Then we use the return pointer to return to the common parent.</p><p>If we now check the call stack with this implementation, here’s what we’re going to see:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/436/1*ybVgRoNf-dBxR_OKxn4oKQ.gif" /></figure><p>As you can see, the stack doesn’t grow as we walk down the tree. But if now put the debugger into the doWork function and log node names, we’re going to see the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/320/1*ErzqXpJt5KkLKxHCn31hmA.gif" /></figure><p><strong>It looks like a callstack in a browser.</strong> So with this algorithm, we’re effectively replacing the browser’s implementation of the call stack with our own implementation. That’s what Andrew describes here:</p><blockquote>Fiber is re-implementation of the stack, specialized for React components. You can think of a single fiber as a virtual stack frame.</blockquote><p>Since we’re now controlling the stack by keeping the reference to the node that acts as a top frame:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2ec6bd5c7607896d76983123ef334834/href">https://medium.com/media/2ec6bd5c7607896d76983123ef334834/href</a></iframe><p>we can stop the traversal at any time and resume to it later. That’s exactly the condition we wanted to achieve to be able to use the new requestIdleCallback API.</p><h3>Work loop in React</h3><p><a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L1118">Here’s the code</a> that implements work loop in React:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ed2d8a131c5d531660abf05efc242240/href">https://medium.com/media/ed2d8a131c5d531660abf05efc242240/href</a></iframe><p>As you can see, it maps nicely to the algorithm I presented above. It keeps the reference to the current fiber node in the nextUnitOfWork variable that acts as a top frame.</p><p>The algorithm can walk the components tree <strong>synchronously </strong>and perform the work for each fiber node in the tree (nextUnitOfWork). This is usually the case for so-called interactive updates caused by UI events (click, input etc). Or it can walk the components tree <strong>asynchronously </strong>checking if there’s time left after performing work for a Fiber node. The function shouldYield returns the result based on <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L1806">deadlineDidExpire</a> and <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L1809">deadline</a> variables that are constantly updated as React performs work for a fiber node.</p><p>The <strong>peformUnitOfWork</strong> function is described in depth <a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e#1a7d">here</a>.</p><h4>I’m working on the series of in-depth articles that explore the implementation details of Fiber change detection algorithm in React. <strong>Stay tuned and follow me on </strong><a href="https://twitter.com/maxkoretskyi"><strong>Twitter</strong></a><strong> and on </strong><a href="https://medium.com/@maxim.koretskyi"><strong>Medium</strong></a><strong>, I’ll tweet as soon as it’s ready.</strong></h4><h4>Thanks for reading! If you liked this article, hit that clap button below 👏. It means a lot to me and it helps other people see the story.</h4><figure><a href="https://react-grid.ag-grid.com/?utm_source=medium&amp;utm_medium=banner&amp;utm_campaign=reactcustom"><img alt="" src="https://cdn-images-1.medium.com/max/500/1*AqX3Hf4h2icjt8WkIuzv6A.png" /></a><figcaption>React Grid — the fastest and most feature-rich grid component from ag-Grid</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=67f1014d0eb7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/react-in-depth/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7">The how and why on React’s usage of linked list in Fiber</a> was originally published in <a href="https://medium.com/react-in-depth">React In Depth</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[In-depth explanation of state and props update in React]]></title>
            <link>https://medium.com/react-in-depth/in-depth-explanation-of-state-and-props-update-in-react-51ab94563311?source=rss----e862e06fcbd9---4</link>
            <guid isPermaLink="false">https://medium.com/p/51ab94563311</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Max Koretskyi]]></dc:creator>
            <pubDate>Tue, 11 Dec 2018 08:00:45 GMT</pubDate>
            <atom:updated>2020-02-26T07:03:48.450Z</atom:updated>
            <content:encoded><![CDATA[<h4>A glimpse into the internals of React Fiber</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*YVF_hZ9hBwHdaXre1Nfq-w.png" /></figure><blockquote><a href="https://medium.com/react-in-depth"><strong><em>ReactInDepth</em></strong></a><strong><em> is moving away from Medium. </em></strong><a href="https://indepth.dev/in-depth-explanation-of-state-and-props-update-in-react/"><strong><em>This article</em></strong></a><strong><em>, its updates and more recent articles are hosted on the new platform </em></strong><a href="https://indepth.dev/"><strong><em>inDepth.dev</em></strong></a></blockquote><p>In my previous article <a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e">Inside Fiber: in-depth overview of the new reconciliation algorithm in React</a> I laid the foundation required to understand the technical details of the update process that I’ll describe in this article.</p><p>I’ve outlined main data structure and concepts that I’ll be using in this article, particularly Fiber nodes, current and work-in-progress trees, side-effects and the effects list. I’ve also provided a high-level overview of the main algorithm and explained the difference between the <strong>render</strong> and <strong>commit</strong> phases. If you haven’t read it, I recommend that you start there.</p><p>I’ve also introduced you to the sample application with a button that simply increments a number rendered on the screen:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/210/1*jTWOx6Yr6JyBV5ETnp4TRQ.gif" /></figure><p>You can play with it <a href="https://stackblitz.com/edit/react-jwqn64">here</a>. It’s implemented as a simple component that returns two child elements <strong>button</strong> and <strong>span</strong> from the <strong>render</strong> method. As you click on the button, the state of the component is updated inside the handler. This results in the text update for the <strong>span</strong> element:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/678394c93fd5d9cbc7bae262ff56bbe4/href">https://medium.com/media/678394c93fd5d9cbc7bae262ff56bbe4/href</a></iframe><p>Here I’ve also added the <strong>componentDidUpdate</strong> lifecycle method to the component. This is needed to demonstrate how React adds <a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e#b30b">effects</a> to call this method during the <strong>commit</strong> phase.</p><p>In this article I want to show you how React processes state updates and builds the effects list. We’ll take a tour into what’s going on in the high-level functions for the <strong>render</strong> and <strong>commit</strong> phases.</p><p>Particularly, we’ll see how that in <a href="https://github.com/facebook/react/blob/cbbc2b6c4d0d8519145560bd8183ecde55168b12/packages/react-reconciler/src/ReactFiberCompleteWork.js#L532"><strong>completeWork</strong></a> React:</p><ul><li>updates the <strong>count</strong> property in the <strong>state</strong> of <strong>ClickCounter</strong></li><li>calls the <strong>render</strong> method to get a list of children and performs comparison</li><li>updates the props for the <strong>span</strong> element</li></ul><p>And, in <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L523"><strong>commitRoot</strong></a> React:</p><ul><li>updates the <strong>textContent</strong> property of the <strong>span</strong> element</li><li>calls the <strong>componentDidUpdate</strong> lifecycle method</li></ul><p>But before that, let’s quickly take a look at how the work is scheduled when we call <strong>setState</strong> in a click handler.</p><p><strong>Note that you don’t need to know any of it to use React. This article is about how React works internally.</strong></p><blockquote>I work as a Developer Advocate at <a href="https://react-grid.ag-grid.com/?utm_source=medium&amp;utm_medium=blog&amp;utm_campaign=reactcustom"><strong>ag-Grid</strong></a>. If you’re curious to learn about data grids or looking for the ultimate React data grid solution, get in touch or give it a try with the guide “<a href="https://blog.ag-grid.com/react-get-started-with-react-grid-in-5-minutes/?utm_source=medium&amp;utm_medium=blog&amp;utm_campaign=getstartedangular"><strong>Get started with React grid in 5 minutes</strong></a>”. I’m happy to answer any questions you may have. <a href="https://twitter.com/maxkoretskyi"><strong>Follow me to stay tuned</strong></a><strong>!</strong></blockquote><h4>Scheduling updates</h4><p>When we click on the button, the <strong>click</strong> event is triggered and React executes the callback that we pass in the button props. In our application it simply increments the counter and updates the state:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f8e8e7b804ff410ab407c13bab858c84/href">https://medium.com/media/f8e8e7b804ff410ab407c13bab858c84/href</a></iframe><p>Every React component has an associated <strong>updater</strong> which acts as a bridge between the components and the React core. This allows <strong>setState</strong> to be implemented differently by ReactDOM, React Native, server side rendering, and testing utilities.</p><p>In this article we’ll be looking at the implementation of the updater object in ReactDOM, which uses the Fiber reconciler. For the <strong>ClickCounter</strong> component it’s a <a href="https://github.com/facebook/react/blob/6938dcaacbffb901df27782b7821836961a5b68d/packages/react-reconciler/src/ReactFiberClassComponent.js#L186"><strong>classComponentUpdater</strong></a>. It’s responsible for retrieving an instance of Fiber, queuing updates, and scheduling the work.</p><p>When updates are queued, they are basically just added to the queue of updates to process on a Fiber node. In our case, <a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e#716a">the Fiber node</a> corresponding to the <strong>ClickCounter</strong> component will have the following structure:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5974f383675e2e9b634110ddfb4eb055/href">https://medium.com/media/5974f383675e2e9b634110ddfb4eb055/href</a></iframe><p>As you can see, the function in the <strong>updateQueue.firstUpdate.next.payload</strong> is the callback we passed to <strong>setState</strong> in the <strong>ClickCounter</strong> component. It represents the first update that needs to be processed during the <strong>render</strong> phase.</p><h4>Processing updates for the ClickCounter Fiber node</h4><p><a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e#1a7d">The chapter on the work loop</a> in my previous article explains the role of the <strong>nextUnitOfWork</strong> global variable. Particularly, it states that this variable holds a reference to the Fiber node from the <strong>workInProgress</strong> tree that has some work to do. As React traverses the tree of Fibers, it uses this variable to know if there’s any other Fiber node with unfinished work.</p><p>Let’s start with the assumption that the <strong>setState</strong> method has been called. React adds the callback from <strong>setState</strong> to the <strong>updateQueue</strong> on the <strong>ClickCounter</strong> fiber node and and schedules work. React enters the <strong>render</strong> phase. It starts traversing from the topmost <strong>HostRoot</strong> Fiber node using the <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L1132">renderRoot</a> function. However, it bails out of (skips) the already processed Fiber nodes until it finds a node with unfinished work. At this point there’s only one Fiber node with some work to do. It’s the <strong>ClickCounter</strong> Fiber node.</p><p>All work is performed on the cloned copy of this Fiber node is stored in the <strong>alternate</strong> field. If the alternate node is not yet created, React creates the copy in the function <a href="https://github.com/facebook/react/blob/769b1f270e1251d9dbdce0fcbd9e92e502d059b8/packages/react-reconciler/src/ReactFiber.js#L326">createWorkInProgress</a> before processing updates. Let’s assume that the variable <strong>nextUnitOfWork</strong> holds a reference to the alternate <strong>ClickCounter</strong> Fiber node.</p><h4>beginWork</h4><p>First, our Fiber gets into the <a href="https://github.com/facebook/react/blob/cbbc2b6c4d0d8519145560bd8183ecde55168b12/packages/react-reconciler/src/ReactFiberBeginWork.js#L1489">beginWork</a> function.</p><blockquote>Since this function is executed for every Fiber node in a tree it’s a good place to put a breakpoint if you want to debug the <strong><em>render</em></strong> phase. I do that often and check the type of a Fiber node to pin down the one I need.</blockquote><p>The <strong>beginWork</strong> function is basically a big switch statement that determines the type of work that needs to be done for a Fiber node by the tag and then executes the respective function to perform the work. In the case of <strong>CountClicks</strong> it’s a class component, so this branch will be taken:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/af9ae60a8a0f203e6e16b1bb5c549b38/href">https://medium.com/media/af9ae60a8a0f203e6e16b1bb5c549b38/href</a></iframe><p>and we get into the <a href="https://github.com/facebook/react/blob/1034e26fe5e42ba07492a736da7bdf5bf2108bc6/packages/react-reconciler/src/ReactFiberBeginWork.js#L428"><strong>updateClassComponent</strong></a> function. Depending on whether it’s the first rendering of a component, work being resumed, or a React update, React either creates an instance and mounts the component or just updates it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7f584c0f09a0a4a743af43edf753bfa4/href">https://medium.com/media/7f584c0f09a0a4a743af43edf753bfa4/href</a></iframe><h4>Processing updates for the ClickCounter Fiber</h4><p>We already have an instance of the <strong>ClickCounter</strong> component, so we get into the <a href="https://github.com/facebook/react/blob/6938dcaacbffb901df27782b7821836961a5b68d/packages/react-reconciler/src/ReactFiberClassComponent.js#L976"><strong>updateClassInstance</strong></a>. That’s where React performs most of the work for class components. Here are the most important operations performed in the function in the order of execution:</p><ul><li>call <strong>UNSAFE_componentWillReceiveProps()</strong> hook (deprecated)</li><li>process updates in the <strong>updateQueue</strong> and generate new state</li><li>call <strong>getDerivedStateFromProps</strong> with this new state and get the result</li><li>call the <strong>shouldComponentUpdate</strong> to ensure a component wants to update; <br>if <strong>false</strong>, skip the whole rendering process, including calling <strong>render</strong> on this component and its children; otherwise proceed with the update</li><li>call <strong>UNSAFE_componentWillUpdate</strong>(deprecated)</li><li>add an effect to trigger <strong>componentDidUpdate </strong>lifecycle hook</li></ul><blockquote>Although the effect to call <strong><em>componentDidUpdate</em></strong> is added in the <strong><em>render</em></strong> phase, the method will be executed in the following <strong><em>commit</em></strong> phase.</blockquote><ul><li>update <strong>state</strong> and <strong>props</strong> on the component instance</li></ul><blockquote><strong>state</strong> and <strong>props</strong> should be updated on the component instance before the <strong>render</strong> method is called, since the <strong>render</strong> method output usually depends on the <strong>state</strong> and <strong>props</strong>. If we don’t do that, it will be returning the same output every time.</blockquote><p>Here’s the simplified version of the function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ebfc669e72b5a11b26a651bbb3aeb03e/href">https://medium.com/media/ebfc669e72b5a11b26a651bbb3aeb03e/href</a></iframe><p>I’ve removed some auxiliary code in the snippet above. For instance, before calling lifecycle methods or adding effects to trigger them, React checks if a component implements the method using the<strong>typeof</strong> operator. Here is, for example, how React checks for the <strong>componentDidUpdate</strong> method before adding the effect:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/74cd6341a55ca717be341a97fdda834e/href">https://medium.com/media/74cd6341a55ca717be341a97fdda834e/href</a></iframe><p>Okay, so now we know what operations are performed for the <strong>ClickCounter</strong> Fiber node during the render phase. Let’s now see how these operations change values on the Fiber nodes. When React begins work, the Fiber node for the <strong>ClickCounter</strong> component looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/623501e66a6a9fc0917de4081421e920/href">https://medium.com/media/623501e66a6a9fc0917de4081421e920/href</a></iframe><p>After the work is completed, we end up with a Fiber node that looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/50a4650335d1c84d42cb19af461a2498/href">https://medium.com/media/50a4650335d1c84d42cb19af461a2498/href</a></iframe><p><strong>Take a moment to observe the differences in properties values.</strong></p><p>After the update is applied, the value of the property <strong>count</strong> is changed to <strong>1</strong> in the <strong>memoizedState</strong> and the <strong>baseState</strong> in <strong>updateQueue</strong>. React has also updated the state in the <strong>ClickCounter</strong> component instance.</p><p>At this point, we no longer have updates in the queue, so <strong>firstUpdate</strong> is <strong>null</strong>. And importantly, we have changes in the <strong>effectTag</strong> property. It’s no longer <strong>0</strong>, it’s value is <strong>4</strong>. In binary this is <strong>100</strong>, which means that the third bit is set, which is exactly the bit for the <strong>Update</strong> <a href="https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/shared/ReactSideEffectTags.js">side-effect tag</a>:</p><pre><strong>export const Update = 0b00000000100;</strong></pre><p>So to conclude, when working on the parent <strong>ClickCounter</strong> Fiber node, React calls the pre-mutation lifecycle methods, updates the state and defines relevant side-effects.</p><h4>Reconciling children for the ClickCounter Fiber</h4><p>Once that’s done, React gets into the <a href="https://github.com/facebook/react/blob/340bfd9393e8173adca5380e6587e1ea1a23cefa/packages/react-reconciler/src/ReactFiberBeginWork.js#L355">finishClassComponent</a>. This is where React calls the <strong>render</strong> method on a component instance and applies its diffing algorithm to the children returned by the component. The high-level overview is described <a href="https://reactjs.org/docs/reconciliation.html#the-diffing-algorithm">in the docs</a>. Here’s the relevant part:</p><blockquote>When comparing two React DOM elements of the same type, React looks at the attributes of both, keeps the same underlying DOM node, and only updates the changed attributes.</blockquote><p>If we dig deeper, however, we can learn that it actually compares Fiber nodes with React elements. But I won’t go into much details now as the process is quite elaborate. I’ll write a separate piece that focuses particular on the process of child reconciliation.</p><blockquote>If you’re anxious to learn details on your own, check out the <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactChildFiber.js#L732">reconcileChildrenArray</a> function since in our application the <strong>render</strong> method returns an array of React Elements.</blockquote><p>At this point there are two things that are important to understand. <strong>First</strong>, as React goes through the child reconciliation process, <strong>it creates or updates Fiber nodes for the child React elements</strong> returned from the <strong>render</strong> method. The <strong>finishClassComponent</strong> function returns the reference to the first child of the current Fiber node. It will be assigned to the <strong>nextUnitOfWork</strong> and processed later in the work loop. <strong>Second</strong>, React <strong>updates the props on the children</strong> as part of work performed for the parent. To do that it uses data from the React elements returned from <strong>render</strong> method.</p><p>For example, here’s what the Fiber node corresponding to the <strong>span</strong> element looks like before React reconciles the children for the <strong>ClickCounter</strong> fiber:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/87c06e1e7586288c83022d70111e2c52/href">https://medium.com/media/87c06e1e7586288c83022d70111e2c52/href</a></iframe><p>As you can see, the <strong>children</strong> property in both <strong>memoizedProps</strong> and <strong>pendingProps</strong> is <strong>0</strong>. Here’s the structure of the React element returned from the <strong>render</strong> for the <strong>span</strong> element:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bb823b3079f1a2d2c1a87c31d289620b/href">https://medium.com/media/bb823b3079f1a2d2c1a87c31d289620b/href</a></iframe><p>As you can see, <strong>there’s a difference between the props</strong> in the Fiber node and the returned React element. Inside the <a href="https://github.com/facebook/react/blob/769b1f270e1251d9dbdce0fcbd9e92e502d059b8/packages/react-reconciler/src/ReactFiber.js#L326"><strong>createWorkInProgress</strong></a> function that is used to create alternate Fiber nodes, <strong>React will copy the updated properties from the React element to the Fiber node</strong>.</p><p>So, after React has finished reconciling the children for the <strong>ClickCounter</strong> component, the <strong>span</strong> Fiber node will have the <strong>pendingProps</strong> updated. They will match the value in the <strong>span</strong> React element:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/75180e23a857179c4999f722bfee221b/href">https://medium.com/media/75180e23a857179c4999f722bfee221b/href</a></iframe><p>Later, when React will be performing work for the <strong>span</strong> Fiber node, it will copy them to the <strong>memoizedProps</strong> and add effects to update DOM.</p><p>Well, that’s all the work that React performs for the <strong>ClickCounter</strong> fiber node during the render phase. Since the button is the first child of the <strong>ClickCounter</strong> component, it will be assigned to the <strong>nextUnitOfWork </strong>variable. There’s nothing to be done with it, so React will move to its sibling, which is <strong>span</strong> Fiber node. According to the algorithm <a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e#25fb">described here</a>, it happens in the <strong>completeUnitOfWork</strong> function.</p><h4>Processing updates for the Span fiber</h4><p>So, the variable <strong>nextUnitOfWork</strong> now points to the alternate of the <strong>span</strong> fiber and React starts working on it. Similar to the steps performed for the <strong>ClickCounter</strong>, we start with the <a href="https://github.com/facebook/react/blob/cbbc2b6c4d0d8519145560bd8183ecde55168b12/packages/react-reconciler/src/ReactFiberBeginWork.js#L1489">beginWork</a> function.</p><p>Since our <strong>span</strong> node is of <strong>HostComponent</strong> type, this time in the switch statement React takes this branch:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/51af6b3d6da79290aee3f58452725eee/href">https://medium.com/media/51af6b3d6da79290aee3f58452725eee/href</a></iframe><p>and ends up in the <a href="https://github.com/facebook/react/blob/cbbc2b6c4d0d8519145560bd8183ecde55168b12/packages/react-reconciler/src/ReactFiberBeginWork.js#L686"><strong>updateHostComponent</strong></a> function. You can see a parallel with the <strong>updateClassComponent</strong> function called for class components. For a functional component it’ll be <strong>updateFunctionComponent</strong> and so on. You can find all these functions in the <a href="https://github.com/facebook/react/blob/1034e26fe5e42ba07492a736da7bdf5bf2108bc6/packages/react-reconciler/src/ReactFiberBeginWork.js"><strong>ReactFiberBeginWork.js</strong></a> file.</p><h4>Reconciling children for the span fiber</h4><p>In our case there nothing important happening for the <strong>span</strong> node in the <strong>updateHostComponent</strong>.</p><h4>Completing work for the Span Fiber node</h4><p>Once <strong>beginWork</strong> is finished, the node gets into the <strong>completeWork</strong> function. But before that, React needs to update the <strong>memoizedProps</strong> on the span fiber. You may remember that when reconciling children for the <strong>ClickCounter</strong> component, React updated the <strong>pendingProps</strong> on the <strong>span</strong> Fiber node:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/75180e23a857179c4999f722bfee221b/href">https://medium.com/media/75180e23a857179c4999f722bfee221b/href</a></iframe><p>So once <strong>beginWork</strong> is finished for the <strong>span</strong> fiber, React updates <strong>pendingProps</strong> to match <strong>memoizedProps</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/265d63a72b0e5366295ae36b4e753af5/href">https://medium.com/media/265d63a72b0e5366295ae36b4e753af5/href</a></iframe><p>It then calls the <strong>completeWork</strong> function which is basically a big switch statement similar to the one we saw in <strong>beginWork</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cbb5dc11e657fe41bc2c0a0afcc327ec/href">https://medium.com/media/cbb5dc11e657fe41bc2c0a0afcc327ec/href</a></iframe><p>Since our <strong>span</strong> Fiber node is <strong>HostComponent</strong>, it runs the <a href="https://github.com/facebook/react/blob/cbbc2b6c4d0d8519145560bd8183ecde55168b12/packages/react-reconciler/src/ReactFiberBeginWork.js#L686"><strong>updateHostComponent</strong></a> function. In this function React basically does the following:</p><ul><li>prepares the DOM updates</li><li>adds them to <strong>updateQueue</strong> of the <strong>span</strong> fiber</li><li>adds the effect to update the DOM</li></ul><p>Before these operations are performed, the <strong>span</strong> Fiber node looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7e36d8bb75593131b8f60d02886c0b50/href">https://medium.com/media/7e36d8bb75593131b8f60d02886c0b50/href</a></iframe><p>and when the work is completed it looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/73cc8d945a533869244cc16c58724765/href">https://medium.com/media/73cc8d945a533869244cc16c58724765/href</a></iframe><p>Notice the difference in the <strong>effectTag</strong> and <strong>updateQueue</strong> fields. It’s no longer <strong>0</strong>, it’s value is <strong>4</strong>. In binary this is <strong>100</strong>, which means that the third bit is set, which is exactly the bit for the <strong>Update</strong> side-effect tag. That’s the only job React needs to do for this node during the following commit phase. The <strong>updateQueue</strong> field holds the payload that will be used for the update.</p><p>Once React has processed <strong>ClickCounter</strong> and its children, it’s done with the <strong>render</strong> phase. It can now assign the completed alternate tree to the <strong>finishedWork</strong> property on <strong>FiberRoot</strong>. This is the new tree that needs to be flushed to the screen. It can be processed immediately after the <strong>render</strong> phase or picked up later when React is given time by the browser.</p><h4>Effects list</h4><p>In our case, since the span node and the ClickCounter component have side effects, React will add a link to the span Fiber node to the firstEffect property of HostFiber.</p><p>React builds the effects list in the <a href="https://github.com/facebook/react/blob/d5e1bf07d086e4fc1998653331adecddcd0f5274/packages/react-reconciler/src/ReactFiberScheduler.js#L999"><strong>compliteUnitOfWork</strong></a> function. Here’s what a Fiber tree with effects to update text of the <strong>span</strong> node and calls hooks on <strong>ClickCounter</strong> looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/460/1*TRmFSeuOuWlY3HXh86cvDA.png" /></figure><p>And here’s the linear list of nodes with effects:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/529/1*ekyRg-8mqawxWoTpcPvM1w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*7CImQFZPe816uJN9FPSWxQ.png" /></figure><h3>Commit phase</h3><p>This phase begins with the function <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L2306">completeRoot</a>. Before it gets to do any work, it sets the <strong>finishedWork</strong> property on the <strong>FiberRoot</strong> to <strong>null</strong>:</p><pre><strong>root.finishedWork = null;</strong></pre><p>Unlike the first <strong>render</strong> phase, the <strong>commit</strong> phase is always synchronous so it can safely update <strong>HostRoot</strong> to indicate that the commit work has started.</p><p>The <strong>commit</strong> phase is where React updates the DOM and calls the post mutation lifecycle method <strong>componentDidUpdate</strong>. To do that, it goes over the list of effects it constructed during the previous <strong>render</strong> phase and applies them.</p><p>We have the following effects defined in the <strong>render</strong> phase for our <strong>span</strong> and <strong>ClickCounter</strong> nodes:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6bd19909b50ab011c4bbeb84f14b6a10/href">https://medium.com/media/6bd19909b50ab011c4bbeb84f14b6a10/href</a></iframe><p>The value of the effect tag for <strong>ClickCounter </strong>is <strong>5 </strong>or <strong>101 </strong>in binary and defines the <strong>Update </strong>work which basically translates into the <strong>componentDidUpdate </strong>lifecycle method for class components. The least significant bit is also set to signal that all work has been completed for this Fiber node in the <strong>render </strong>phase.</p><p>The value of the effect tag for <strong>span</strong> is <strong>4</strong> or <strong>100</strong> in binary and defines the <strong>update </strong>work for the host component DOM update. In the case of the <strong>span </strong>element, React will need to update <strong>textContent </strong>for the element.</p><h4>Applying effects</h4><p>Let’s see how React applies those effects. The function <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L523"><strong>commitRoot</strong></a>, which is used to apply the effects, consists of 3 sub-functions:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/42eaa612c0249e10ec282d43a4d9148d/href">https://medium.com/media/42eaa612c0249e10ec282d43a4d9148d/href</a></iframe><p>Each of those sub-functions implements a loop that iterates over the list of effects and checks the types of the effects. When it finds the effect pertaining to the function’s purpose, it applies it. In our case, it will call the <strong>componentDidUpdate</strong> lifecycle method on the <strong>ClickCounter</strong> component and update the text of the <strong>span</strong> element.</p><p>The first function <a href="https://github.com/facebook/react/blob/fefa1269e2a67fa5ef0992d5cc1d6114b7948b7e/packages/react-reconciler/src/ReactFiberCommitWork.js#L183">commitBeforeMutationLifeCycles</a> looks for the <a href="https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/shared/ReactSideEffectTags.js#L25"><strong>Snapshot</strong></a> effect and calls the <strong>getSnapshotBeforeUpdate</strong> method. But, since we didn’t implement the method on the <strong>ClickCounter</strong> component, React didn’t add the effect during the <strong>render</strong> stage. So in our case, this function does nothing.</p><h4>DOM updates</h4><p>Next React moves to the <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L376"><strong>commitAllHostEffects</strong></a> function. This is where React will change the text on the <strong>span</strong> element from <strong>0</strong> to <strong>1</strong>. There’s nothing to do for the <strong>ClickCounter</strong> fiber because nodes corresponding to class components don’t have any DOM updates.</p><p>The gist of the function is that it selects the correct type of effect and applies the corresponding operations. In our case we need to update the text on the <strong>span</strong> element, so we take the <strong>Update</strong> branch here:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c939ec5cfdb4c0bf652cde91d22cc7fa/href">https://medium.com/media/c939ec5cfdb4c0bf652cde91d22cc7fa/href</a></iframe><p>By going down to <strong>commitWork</strong>, we will eventually get into the <a href="https://github.com/facebook/react/blob/8a8d973d3cc5623676a84f87af66ef9259c3937c/packages/react-dom/src/client/ReactDOMComponent.js#L326"><strong>updateDOMProperties</strong></a> function. It takes the <strong>updateQueue</strong> payload that was added during the render stage to the Fiber node, and updates the <strong>textContent</strong> property on the <strong>span</strong> element:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5f2743e148600e4c49edfaa84be44b8a/href">https://medium.com/media/5f2743e148600e4c49edfaa84be44b8a/href</a></iframe><p>After the DOM updates have been applied, React assigns the <strong>finishedWork</strong> tree to the <strong>HostRoot</strong>. It sets an alternate tree as current:</p><pre><strong>root.current = finishedWork;</strong></pre><h4>Calling post mutation lifecycle hooks</h4><p>The last remaining function is <a href="https://github.com/facebook/react/blob/d5e1bf07d086e4fc1998653331adecddcd0f5274/packages/react-reconciler/src/ReactFiberScheduler.js#L479"><strong>commitAllLifecycles</strong></a>. This where React calls the post mutational lifecycle methods. During the <strong>render</strong> phase, React added the <strong>Update</strong> effect to the <strong>ClickCounter</strong> component. This is one of the effects that the function <strong>commitAllLifecycles</strong> looks for and calls <strong>componentDidUpdate</strong> method:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ed103df6e559afe1bd7f996b00f2210d/href">https://medium.com/media/ed103df6e559afe1bd7f996b00f2210d/href</a></iframe><p>The function also updates <a href="https://reactjs.org/docs/refs-and-the-dom.html">refs</a>, but since we don’t have any this functionality won’t be used. The method is called in the <a href="https://github.com/facebook/react/blob/e58ecda9a2381735f2c326ee99a1ffa6486321ab/packages/react-reconciler/src/ReactFiberCommitWork.js#L351"><strong>commitLifeCycles</strong></a> function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9dcf669f7a2b4048a11e2daaaedfe899/href">https://medium.com/media/9dcf669f7a2b4048a11e2daaaedfe899/href</a></iframe><p>You can also see that this is the function where React calls the <strong>componentDidMount</strong> method for components that have been rendered for the first time.</p><p>And that’s it!</p><p>We’re finally done. Let me know what you think about the article or ask questions in the comments. I have many more articles in the works providing in-depth explanation for scheduler, children reconciliation process and how effects list is built. I also have plans to create a video where I’ll show how to debug the application using this article as a basis.</p><h4>For more insights follow me on <a href="https://twitter.com/maxkoretskyi">Twitter</a> and on <a href="https://medium.com/@maxim.koretskyi">Medium</a>. Thanks for reading! If you liked this article, hit that clap button below 👏. It means a lot to me and it helps other people see the story.</h4><figure><a href="https://react-grid.ag-grid.com/?utm_source=medium&amp;utm_medium=banner&amp;utm_campaign=reactcustom"><img alt="" src="https://cdn-images-1.medium.com/max/500/1*AqX3Hf4h2icjt8WkIuzv6A.png" /></a><figcaption>React Grid — the fastest and most feature-rich grid component from ag-Grid</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=51ab94563311" width="1" height="1" alt=""><hr><p><a href="https://medium.com/react-in-depth/in-depth-explanation-of-state-and-props-update-in-react-51ab94563311">In-depth explanation of state and props update in React</a> was originally published in <a href="https://medium.com/react-in-depth">React In Depth</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Inside Fiber: in-depth overview of the new reconciliation algorithm in React]]></title>
            <link>https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e?source=rss----e862e06fcbd9---4</link>
            <guid isPermaLink="false">https://medium.com/p/e1c04700ef6e</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[reactjs]]></category>
            <dc:creator><![CDATA[Max Koretskyi]]></dc:creator>
            <pubDate>Tue, 27 Nov 2018 09:42:53 GMT</pubDate>
            <atom:updated>2020-02-16T10:36:07.496Z</atom:updated>
            <content:encoded><![CDATA[<h4>The how and why on everything from React elements to Fiber nodes</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/691/1*8Xi7apFuZ2M5Fw3CirwyDw.png" /></figure><blockquote><a href="https://medium.com/react-in-depth"><strong><em>ReactInDepth</em></strong></a><strong><em> is moving away from Medium. </em></strong><a href="https://indepth.dev/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react/"><strong><em>This article</em></strong></a><strong><em>, its updates and more recent articles are hosted on the new platform </em></strong><a href="https://indepth.dev/"><strong><em>inDepth.dev</em></strong></a></blockquote><p>React is a JavaScript library for building user interfaces. At its core lies <a href="https://medium.freecodecamp.org/what-every-front-end-developer-should-know-about-change-detection-in-angular-and-react-508f83f58c6a">the mechanism</a> that tracks changes in a component state and projects the updated state to the screen. In React we know this process as <strong>reconciliation</strong>. We call the setState method and the framework checks if the state or props have changed and re-renders a component on UI.</p><p>React’s docs provide <a href="https://reactjs.org/docs/reconciliation.html">a good high-level overview</a> of the mechanism: the role of React elements, lifecycle methods and the render method, and the diffing algorithm applied to a component’s children. The tree of immutable React elements returned from the render method is commonly known as the “virtual DOM”. That term helped explain React to people early on, but it also caused confusion and isn’t used in the React documentation anymore. In this article I’ll stick to calling it a tree of React elements.</p><p>Besides the tree of React elements, the framework has always had a tree of internal instances (components, DOM nodes etc.) used to keep the state. Starting from version 16, React rolled out a new implementation of that internal instances tree and the algorithm that manages it code-named <strong>Fiber</strong>. To learn about the advantages which the Fiber architecture brings check out <a href="https://medium.com/dailyjs/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7">The how and why on React’s usage of linked list in Fiber</a>.</p><blockquote>This article would take me a lot longer to write and would be less comprehensive without the help of <a href="https://medium.com/u/a3a8af6addc1">Dan Abramov</a>! <em>👍</em></blockquote><p>This is the first article in the series aimed at teaching you internal architecture of React. In this article I want to provide an in-depth overview of important concepts and data structures relevant to the algorithm. Once we have enough background, we’ll explore the algorithm and main functions used to traverse and process the fiber tree. Next articles in the series will demonstrate how React uses the algorithm to perform initial render and process state and props updates. From there we’ll move on to the details of the scheduler, the child reconciliation process, and the mechanism of building an effects list.</p><p><a href="https://twitter.com/maxkoretskyi"><strong>Follow me to stay tuned!</strong></a></p><p>I’m going to give you some pretty advanced knowledge here 🧙‍. I encourage you to read it to understand the magic behind the inner workings of Concurrent React. This series of articles will also serve you as a great guide if you plan to start contributing to React. I’m <a href="https://blog.angularindepth.com/level-up-your-reverse-engineering-skills-8f910ae10630">a strong believer in reverse-engineering</a>, so there will be a lot of links to the sources from the recent version 16.6.0.</p><p>It’s definitely quite a lot to take in, so don’t feel stressed if you don’t understand something right away. It takes time as everything worthwhile. <strong>Note that you don’t need to know any of it to use React. This article is about how React works internally.</strong></p><blockquote>I work as a Developer Advocate at <a href="https://react-grid.ag-grid.com/?utm_source=medium&amp;utm_medium=blog&amp;utm_campaign=reactcustom"><strong>ag-Grid</strong></a>. If you’re curious to learn about data grids or looking for the ultimate React data grid solution, get in touch or give it a try with the guide “<a href="https://blog.ag-grid.com/react-get-started-with-react-grid-in-5-minutes/?utm_source=medium&amp;utm_medium=blog&amp;utm_campaign=getstartedangular"><strong>Get started with React grid in 5 minutes</strong></a>”. I’m happy to answer any questions you may have.</blockquote><h3>Setting the background</h3><p>Here’s a simple application that I’ll use throughout the series. We have a button that simply increments a number rendered on the screen:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/210/1*jTWOx6Yr6JyBV5ETnp4TRQ.gif" /></figure><p>And here’s the implementation:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/adf080d969e31cd8ca1252c1e6d3a45b/href">https://medium.com/media/adf080d969e31cd8ca1252c1e6d3a45b/href</a></iframe><p>You can play with it <a href="https://stackblitz.com/edit/react-t4rdmh">here</a>. As you can see, it’s a simple component that returns two child elements <strong>button </strong>and <strong>span </strong>from the <strong>render </strong>method. As soon as you click on the button, the state of the component is updated inside the handler. This, in turn, results in the text update for the <strong>span </strong>element.</p><p>There are various activities React performs during <strong>reconciliation</strong>. For example, here are the high-level operations React performs during the first render and after state update in our simple application:</p><ul><li>updates <strong>count </strong>property in the <strong>state </strong>of <strong>ClickCounter</strong></li><li>retrieves and compares children of <strong>ClickCounter </strong>and their props</li><li>updates props for the <strong>span </strong>element</li></ul><p>There are other activities performed during <strong>reconciliation</strong> like calling <a href="https://reactjs.org/docs/react-component.html#updating">lifecycle methods</a> or updating <a href="https://reactjs.org/docs/refs-and-the-dom.html">refs</a>. <strong>All these activities are collectively referred to as “work” in the Fiber architecture. </strong>The type of work usually depends on the type of React element. For example, for a class component, React needs to create an instance, while it doesn’t do that for a functional component. As you know, we have many kinds of elements in React, e.g. class and functional components, host components (DOM nodes), portals etc. The type of React element is defined by the first parameter to the <a href="https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react/src/ReactElement.js#L171">createElement</a> function. This function is generally used in the <strong>render </strong>method to create an element.</p><p>Before we begin our exploration of the activities and the main fiber algorithm, let’s first get ourselves familiar with the data structures used internally by React.</p><h3>From React Elements to Fiber nodes</h3><p>Every component in React has a UI representation we can call a view or a template that’s returned from the <strong>render </strong>method. Here’s the template for our <strong>ClickCounter </strong>component:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ee2c91debd7f9a66a4829db92c8eabc9/href">https://medium.com/media/ee2c91debd7f9a66a4829db92c8eabc9/href</a></iframe><h4>React Elements</h4><p>Once a template goes through the JSX compiler, you end up with a bunch of React elements. This is what’s really returned from the <strong>render </strong>method of React components, not HTML. Since we’re not required to use JSX, the <strong>render </strong>method for our <strong>ClickCounter </strong>component could be re-written like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a6b0ad3cc2e0e246f2d27ee17fd45c3d/href">https://medium.com/media/a6b0ad3cc2e0e246f2d27ee17fd45c3d/href</a></iframe><p>The calls to <strong>React.createElement</strong> in the <strong>render </strong>method will create two data structures like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d7dcb1d0e1b515021cae2a6c49628f90/href">https://medium.com/media/d7dcb1d0e1b515021cae2a6c49628f90/href</a></iframe><p>You can see that React adds the property <a href="https://overreacted.io/why-do-react-elements-have-typeof-property/"><strong>$$typeof</strong></a><strong> </strong>to these objects to uniquely identify them as React elements. Then we have properties <strong>type</strong>, <strong>key </strong>and <strong>props </strong>that describe the element. The values are taken from what you pass to the <strong>React.createElement</strong> function. Notice how React represents text content as children of the <strong>span </strong>and <strong>button </strong>nodes. And how the click handler is part of the <strong>button </strong>element props. There are other fields on React elements like the <strong>ref </strong>field that are beyond the scope of this article.</p><p>The React element for <strong>ClickCounter</strong> doesn’t have any props or a key:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d88b6dac8339f0b3229e39468f926dba/href">https://medium.com/media/d88b6dac8339f0b3229e39468f926dba/href</a></iframe><h4>Fiber nodes</h4><p>During <strong>reconciliation</strong> data from every React element returned from the <strong>render</strong> method is merged into the tree of fiber nodes. Every React element has a corresponding fiber node. Unlike React elements, fibers aren’t re-created on every render. These are mutable data structures that hold components state and DOM.</p><p>We discussed earlier that depending on the type of a React element the framework needs to perform different activities. In our sample application, for the class components <strong>ClickCounter</strong> it calls lifecycle methods and the render method, whereas for the <strong>span</strong> host component (DOM node) it performs DOM mutation. So each React element is converted into a Fiber node of <a href="https://github.com/facebook/react/blob/769b1f270e1251d9dbdce0fcbd9e92e502d059b8/packages/shared/ReactWorkTags.js">corresponding type</a> that describes the work that needs to be done.</p><p><strong>You can think of a fiber as a data structure that represents some work to do or, in other words, a unit of work. Fiber’s architecture also provides a convenient way to track, schedule, pause and abort the work.</strong></p><p>When a React element is converted into a fiber node for the first time, React uses the data from the element to create a fiber in the <a href="https://github.com/facebook/react/blob/769b1f270e1251d9dbdce0fcbd9e92e502d059b8/packages/react-reconciler/src/ReactFiber.js#L414">createFiberFromTypeAndProps</a> function. In the consequent updates React reuses the fiber node and just updates the necessary properties using data from a corresponding React element. React may also need to move the node in the hierarchy based on the key prop or delete it if the corresponding React element is no longer returned from the render method.</p><blockquote>Check out the <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactChildFiber.js#L239"><strong>ChildReconciler</strong></a> function to see the list of all activities and corresponding functions React performs for existing fiber nodes.</blockquote><p>Because React creates a fiber for each React element and since we have a tree of those elements, we’re going to have a tree of fiber nodes. In the case of our sample application it looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/555/1*cLqBZRht7RgR9enHet_0fQ.png" /></figure><p>All fiber nodes are connected through a linked list using the following properties on fiber nodes: <strong>child</strong>, <strong>sibling</strong> and <strong>return</strong>. For more details on why it works this way, check out my article <a href="https://medium.com/dailyjs/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7">The how and why on React’s usage of linked list in Fiber</a> if you haven’t read it already.</p><h4>Current and work in progress trees</h4><p>After the first render, React ends up with a fiber tree that reflects the state of the application that was used to render the UI. This tree is often referred to as <strong>current</strong>. When React starts working on updates it builds a so-called <strong>workInProgress</strong> tree that reflects the future state to be flushed to the screen.</p><p>All work is performed on fibers from the <strong>workInProgress </strong>tree. As React goes through the <strong>current </strong>tree, for each existing fiber node it creates an alternate node that constitutes the <strong>workInProgress </strong>tree. This node is created using the data from React elements returned by the <strong>render </strong>method. Once the updates are processed and all related work is completed, React will have an alternate tree ready to be flushed to the screen. Once this <strong>workInProgress </strong>tree is rendered on the screen, it becomes the <strong>current </strong>tree.</p><p>One of React’s core principles is consistency. React always updates the DOM in one go — it doesn’t show partial results. The <strong>workInProgress</strong> tree serves as a “draft” that’s not visible to the user, so that React can process all components first, and then flush their changes to the screen.</p><p>In the sources you’ll see a lot of functions that take fiber nodes from both the <strong>current </strong>and <strong>workInProgress </strong>trees. Here’s the signature of one such function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1e6164f6be9416ae176f39dcee3db630/href">https://medium.com/media/1e6164f6be9416ae176f39dcee3db630/href</a></iframe><p>Each fiber node holds a reference to its counterpart from the other tree in the <strong>alternate</strong> field. A node from the <strong>current </strong>tree points to the node from the <strong>workInProgress </strong>tree and vice versa.</p><h4>Side-effects</h4><p>We can think of a component in React as a function that uses the state and props to compute the UI representation. Every other activity like mutating the DOM or calling lifecycle methods should be considered a side-effect or, simply, an effect. Effects are also mentioned <a href="https://reactjs.org/docs/hooks-overview.html#%EF%B8%8F-effect-hook">in the docs</a>:</p><blockquote>You’ve likely performed data fetching, subscriptions, or manually <strong>changing the DOM</strong> from React components before. We call these operations “side effects” (or “effects” for short) because they can affect other components and can’t be done during rendering.</blockquote><p>You can see how most state and props updates will lead to side-effects. And since applying effects is a type of work, a fiber node is a convenient mechanism to track effects in addition to updates. Each fiber node can have effects associated with it. They are encoded in the <strong>effectTag</strong> field.</p><p>So effects in Fiber basically define the <a href="https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/shared/ReactSideEffectTags.js">work</a> that needs to be done for instances after updates have been processed. For host components (DOM elements) the work consists of adding, updating or removing elements. For class components React may need to update refs and call the componentDidMount and componentDidUpdate lifecycle methods. There are also other effects corresponding to other types of fibers.</p><h4>Effects list</h4><p>React processes updates very quickly and to achieve that level of performance it employs a few interesting techniques. <strong>One of them is building a linear list of fiber nodes with effects for quick iteration.</strong> Iterating the linear list is much faster than a tree, and there’s no need to spend time on nodes without side-effects.</p><p>The goal of this list is to mark nodes that have DOM updates or other effects associated with them. This list is a subset of the <strong>finishedWork</strong> tree and is linked using the <strong>nextEffect</strong> property instead of the <strong>child</strong> property used in the <strong>current</strong> and <strong>workInProgress</strong> trees.</p><p><a href="https://medium.com/u/a3a8af6addc1">Dan Abramov</a> offered an analogy for an effects list. He likes to think of it as a Christmas tree, with “Christmas lights” binding all effectful nodes together. To visualize this, let’s imagine the following tree of fiber nodes where the highlighted nodes have some work to do. For example, our update caused <strong>c2</strong> to be inserted into the DOM, <strong>d2</strong> and <strong>c1</strong> to change attributes, and <strong>b2</strong> to fire a lifecycle method. The effect list will link them together so React can skip other nodes later:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/475/1*Q0pCNcK1FfCttek32X_l7A.png" /></figure><p>You can see how the nodes with effects are linked together. When going over the nodes, React uses the <strong>firstEffect</strong> pointer to figure out where the list starts. So the diagram above can be represented as a linear list like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/712/1*mbeZ1EsfMsLUk-9hOYyozw.png" /></figure><p>As you can see, React applies effects in the order from children and up to parents.</p><h4>Root of the fiber tree</h4><p>Every React application has one or more DOM elements that act as containers. In our case it’s the <strong>div</strong> element with the ID <strong>container</strong>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/065a45701756889e463c8d48164e1def/href">https://medium.com/media/065a45701756889e463c8d48164e1def/href</a></iframe><p>React creates a <a href="https://github.com/facebook/react/blob/0dc0ddc1ef5f90fe48b58f1a1ba753757961fc74/packages/react-reconciler/src/ReactFiberRoot.js#L31">fiber root</a> object for each of those containers. You can access it using the reference to the DOM element:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c4b3ca2d00a195e24fa4ce8b5efd5f3/href">https://medium.com/media/4c4b3ca2d00a195e24fa4ce8b5efd5f3/href</a></iframe><p>This fiber root is where React holds the reference to a fiber tree. It is stored in the <strong>current</strong> property of the fiber root:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/567d25d93c214e06042ec3a135e1581a/href">https://medium.com/media/567d25d93c214e06042ec3a135e1581a/href</a></iframe><p>The fiber tree starts with <a href="https://github.com/facebook/react/blob/cbbc2b6c4d0d8519145560bd8183ecde55168b12/packages/shared/ReactWorkTags.js#L34">a special type</a> of fiber node which is <strong>HostRoot</strong>. It’s created internally and acts as a parent for your topmost component. There’s a link from the <strong>HostRoot</strong> fiber node back to the <strong>FiberRoot</strong> through the <strong>stateNode</strong> property:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/557c783ca3dc43456bf5a10a7471c1e1/href">https://medium.com/media/557c783ca3dc43456bf5a10a7471c1e1/href</a></iframe><p>You can explore the fiber tree by accessing the topmost <strong>HostRoot</strong> fiber node through the fiber root. Or you can get an individual fiber node from a component instance like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d50d9d5daa22166a540bf76414ec0c52/href">https://medium.com/media/d50d9d5daa22166a540bf76414ec0c52/href</a></iframe><h4>Fiber node structure</h4><p>Let’s now take a look at the structure of fiber nodes created for the <strong>ClickCounter</strong> component</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/260d6684695026c3cdea5c837d5a711a/href">https://medium.com/media/260d6684695026c3cdea5c837d5a711a/href</a></iframe><p>and the <strong>span</strong> DOM element:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/73771242748a6ce5fdb169f281531632/href">https://medium.com/media/73771242748a6ce5fdb169f281531632/href</a></iframe><p>There’s quite a lot of fields on fiber nodes. I’ve described the purpose of the fields <strong>alternate</strong>, <strong>effectTag </strong>and <strong>nextEffect</strong> in previous sections.<strong> </strong>Let’s now see why we need others.</p><p><strong>stateNode</strong><br>Holds the reference to the class instance of a component, a DOM node or other React element type associated with the fiber node. In general, we can say that this property is used to hold the local state associated with a fiber.</p><p><strong>type</strong><br>Defines the function or class associated with this fiber. For class components, it points to the constructor function and for DOM elements it specifies the HTML tag. I use this field quite often to understand what element a fiber node is related to.</p><p><strong>tag<br></strong>Defines <a href="https://github.com/facebook/react/blob/769b1f270e1251d9dbdce0fcbd9e92e502d059b8/packages/shared/ReactWorkTags.js">the type of the fiber</a>. It’s used in the reconciliation algorithm to determine what work needs to be done. As mentioned earlier, the work varies depending on the type of React element. The function <a href="https://github.com/facebook/react/blob/769b1f270e1251d9dbdce0fcbd9e92e502d059b8/packages/react-reconciler/src/ReactFiber.js#L414">createFiberFromTypeAndProps</a> maps a React element to the corresponding fiber node type. In our application, the property <strong>tag</strong> for the <strong>ClickCounter</strong> component is <strong>1</strong> which denotes a <strong>ClassComponent</strong> and for the <strong>span</strong> element it’s <strong>5</strong> denoting a <strong>HostComponent</strong>.</p><p><strong>updateQueue<br></strong>A queue of state updates, callbacks and DOM updates.</p><p><strong>memoizedState</strong><br>State of the fiber that was used to create the output. When processing updates it reflects the state that’s currently rendered on the screen.</p><p><strong>memoizedProps<br></strong>Props of the fiber that were used to create the output during the previous render.</p><p><strong>pendingProps<br></strong>Props that have been updated from new data in React elements and need to be applied to child components or DOM elements.</p><p><strong>key<br></strong>Unique identifier with a group of children to help React figure out which items have changed, have been added or removed from the list. It’s related to the “lists and keys” functionality of React described <a href="https://reactjs.org/docs/lists-and-keys.html#keys">here</a>.</p><p>You can find the complete structure of a fiber node <a href="https://github.com/facebook/react/blob/6e4f7c788603dac7fccd227a4852c110b072fe16/packages/react-reconciler/src/ReactFiber.js#L78">here</a>. I’ve omitted a bunch of fields in the explanation above. Particularly, I skipped the pointers <strong>child</strong>, <strong>sibling</strong> and <strong>return</strong> that make up a tree data structure which I <a href="https://medium.com/dailyjs/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7">described in my previous article</a>. And a category of fields like <strong>expirationTime</strong>, <strong>childExpirationTime </strong>and <strong>mode </strong>that are specific to <strong>Scheduler</strong>.</p><h3>General algorithm</h3><p>React performs work in two main phases: <strong>render </strong>and <strong>commit</strong>.</p><p>During the first <strong>render</strong> phase React applies updates to components scheduled through <strong>setState</strong> or <strong>React.render</strong> and figures out what needs to be updated in the UI. If it’s the initial render, React creates a new fiber node for each element returned from the <strong>render</strong> method. In the following updates, fibers for existing React elements are re-used and updated. <strong>The result of the phase is a tree of fiber nodes marked with side-effects. </strong>The effects describe the work that needs to be done during the following <strong>commit</strong> phase. During this phase React takes a fiber tree marked with effects and applies them to instances. It goes over the list of effects and performs DOM updates and other changes visible to a user.</p><p><strong>It’s important to understand that the work during the first </strong><strong>render phase can be performed asynchronously.</strong> React can process one or more fiber nodes depending on the available time, then stop to stash the work done and yield to some event. It then continues from where it left off. Sometimes though, it may need to discard the work done and start from the top again. These pauses are made possible by the fact that the work performed during this phase doesn’t lead to any user-visible changes, like DOM updates.<strong> In contrast, the following </strong><strong>commit phase is always synchronous</strong>. This is because the work performed during this stage leads to changes visible to the user, e.g. DOM updates. That’s why React needs to do them in a single pass.</p><p>Calling lifecycle methods is one type of work performed by React. Some methods are called during the <strong>render</strong> phase and others during the <strong>commit</strong> phase. Here’s the list of lifecycles called when working through the first <strong>render</strong> phase:</p><ul><li>[UNSAFE_]componentWillMount (deprecated)</li><li>[UNSAFE_]componentWillReceiveProps (deprecated)</li><li>getDerivedStateFromProps</li><li>shouldComponentUpdate</li><li>[UNSAFE_]componentWillUpdate (deprecated)</li><li>render</li></ul><p>As you can see, some legacy lifecycle methods that are executed during the <strong>render</strong> phase are marked as <strong>UNSAFE</strong> from the version 16.3. They are now called legacy lifecycles in the docs. They will be deprecated in future 16.x releases and their counterparts without the <strong>UNSAFE</strong> prefix will be removed in 17.0. You can read more about these changes and the suggested migration path <a href="https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html">here</a>.</p><p>Are you curious about the reason for this?</p><p>Well, we’ve just learned that because the <strong>render</strong> phase doesn’t produce side-effects like DOM updates, React can process updates asynchronously to components asynchronously (potentially even doing it in multiple threads). However, the lifecycles marked with <strong>UNSAFE</strong> have often been misunderstood and subtly misused. Developers tended to put the code with side-effects inside these methods which may cause problems with the new async rendering approach. Although only their counterparts without the <strong>UNSAFE </strong>prefix will be removed, they are still likely to cause issues in the upcoming Concurrent Mode (which you can opt out of).</p><p>Here’s the list of lifecycle methods executed during the second <strong>commit</strong> phase:</p><ul><li>getSnapshotBeforeUpdate</li><li>componentDidMount</li><li>componentDidUpdate</li><li>componentWillUnmount</li></ul><p>Because these methods execute in the synchronous <strong>commit</strong> phase, they may contain side effects and touch the DOM.</p><p>Okay, so now we have the background to take a look at generalized algorithm used to walk the tree and perform work. Let’s dive in.</p><h3>Render phase</h3><p>The reconciliation algorithm always starts from the topmost <strong>HostRoot</strong> fiber node using the <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L1132">renderRoot</a> function. However, React bails out of (skips) already processed fiber nodes until it finds the node with unfinished work. For example, if you call <strong>setState</strong> deep in the components tree, React will start from the top but quickly skip over the parents until it gets to the component that had its <strong>setState</strong> method called.</p><h4>Main steps of the work loop</h4><p>All fiber nodes are processed <a href="https://github.com/facebook/react/blob/f765f022534958bcf49120bf23bc1aa665e8f651/packages/react-reconciler/src/ReactFiberScheduler.js#L1136">in the work loop</a>. Here is the implementation of the synchronous part of the loop:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/951e6380607f99521da182a5b9276f7a/href">https://medium.com/media/951e6380607f99521da182a5b9276f7a/href</a></iframe><p>In the code above, the <strong>nextUnitOfWork</strong> holds a reference to the fiber node from the <strong>workInProgress</strong> tree that has some work to do. As React traverses the tree of Fibers, it uses this variable to know if there’s any other fiber node with unfinished work. After the current fiber is processed, the variable will either contain the reference to the next fiber node in a tree or <strong>null</strong>. In that case React exits the work loop and is ready to commit the changes.</p><p>There are 4 main functions that are used to traverse the tree and initiate or complete the work:</p><ul><li><a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L1056">performUnitOfWork</a></li><li><a href="https://github.com/facebook/react/blob/cbbc2b6c4d0d8519145560bd8183ecde55168b12/packages/react-reconciler/src/ReactFiberBeginWork.js#L1489">beginWork</a></li><li><a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L879">completeUnitOfWork</a></li><li><a href="https://github.com/facebook/react/blob/cbbc2b6c4d0d8519145560bd8183ecde55168b12/packages/react-reconciler/src/ReactFiberCompleteWork.js#L532">completeWork</a></li></ul><p>To demonstrate how they are used, take a look at the following animation of traversing a fiber tree. I’ve used the simplified implementation of these functions for the demo. Each function takes a fiber node to process and as React goes down the tree you can see the currently active fiber node changes. You can clearly see on the video how the algorithm goes from one branch to the other. It first completes the work for children before moving to parents.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*A3-yF-3Xf47nPamFpRm64w.gif" /></figure><blockquote>Note that straight vertical connections denote siblings, whereas bent connections denote children, e.g. <strong>b1</strong> doesn’t have children, while <strong>b2</strong> has one child <strong>c1</strong>.</blockquote><p><a href="https://vimeo.com/302222454">Here’s the link to the video</a> where you can pause the playback and inspect the current node and the state of functions. Conceptually, you can think of “begin” as “stepping into” a component, and “complete” as “stepping out” of it. You can also <a href="https://stackblitz.com/edit/js-ntqfil?file=index.js">play with the example and the implementation here</a> as I explain what these functions do.</p><p>Let’s start with the first two functions <strong>performUnitOfWork</strong> and <strong>beginWork</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/22eba7c7a789a7a98682d6ecf28da1a9/href">https://medium.com/media/22eba7c7a789a7a98682d6ecf28da1a9/href</a></iframe><p>The function <strong>performUnitOfWork</strong> receives a fiber node from the <strong>workInProgress </strong>tree and starts the work by calling <strong>beginWork </strong>function. This is the function that will start all the activities that need to be performed for a fiber. For the purposes of this demonstration, we simply log the name of the fiber to denote that the work has been done. <strong>The function </strong><strong>beginWork always returns a pointer to the next child to process in the loop or </strong><strong>null.</strong></p><p>If there’s a next child, it will be assigned to the variable <strong>nextUnitOfWork</strong> in the <strong>workLoop </strong>function. However, if there’s no child, React knows that it reached the end of the branch and so it can complete the current node. <strong>Once the node is completed, it’ll need to perform work for siblings and backtrack to the parent after that. </strong>This is done in the <strong>completeUnitOfWork</strong> function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3d52fa9e0ccab075c155415222cc7679/href">https://medium.com/media/3d52fa9e0ccab075c155415222cc7679/href</a></iframe><p>You can see that the gist of the function is a big <strong>while</strong> loop. React gets into this function when a <strong>workInProgress</strong> node has no children. After completing the work for the current fiber, it checks if there’s a sibling. If found, React exits the function and returns the pointer to the sibling. It will be assigned to the <strong>nextUnitOfWork</strong> variable and React will perform the work for the branch starting with this sibling. It’s important to understand that at this point React has only completed work for the preceding siblings. It hasn’t completed work for the parent node. <strong>Only once all branches starting with child nodes are completed does it complete the work for the parent node and backtracks.</strong></p><p>As you can see from the implementation, both <strong>performUnitOfWork</strong> and <strong>completeUnitOfWork</strong> are used mostly for iteration purposes, whereas the main activities take place in the <strong>beginWork</strong> and <strong>completeWork </strong>functions. In the following articles in the series we’ll learn what happens for the <strong>ClickCounter</strong> component and the <strong>span</strong> node as React steps into <strong>beginWork</strong> and <strong>completeWork</strong> functions.</p><h4>Commit phase</h4><p>The phase begins with the function <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L2306">completeRoot</a>. This is where React updates the DOM and calls pre and post mutation lifecycle methods.</p><p>When React gets to this phase, it has 2 trees and the effects list. The first tree represents the state currently rendered on the screen. Then there’s an alternate tree built during the <strong>render</strong> phase. It’s called <strong>finishedWork</strong> or <strong>workInProgress</strong> in the sources and represents the state that needs to be reflected on the screen. This alternate tree is linked similarly to the current tree through the <strong>child</strong> and <strong>sibling</strong> pointers.</p><p>And then, there’s an effects list —<strong> </strong>a subset of nodes from the <strong>finishedWork </strong>tree linked through the <strong>nextEffect</strong> pointer. Remember that the effect list is the <em>result</em> of running the <strong>render</strong> phase. The whole point of rendering was to determine which nodes need to be inserted, updated, or deleted, and which components need to have their lifecycle methods called. And that’s what the effect list tells us. <strong>And it’s exactly the set of nodes that’s iterated during the commit phase.</strong></p><blockquote>For debugging purposes, the <strong>current</strong> tree can be accessed through the <strong>current</strong> property of the fiber root. The <strong>finishedWork</strong> tree can be accessed through the <strong>alternate</strong> property of the <strong>HostFiber</strong> node in the current tree.</blockquote><p>The main function that runs during the commit phase is <a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L523">commitRoot</a>. Basically, it does the following:</p><ul><li>Calls the <strong>getSnapshotBeforeUpdate</strong> lifecycle method on nodes tagged with the <strong>Snapshot </strong>effect</li><li>Calls the <strong>componentWillUnmount </strong>lifecycle method on nodes tagged with the <strong>Deletion</strong> effect</li><li>Performs all the DOM insertions, updates and deletions</li><li>Sets the <strong>finishedWork </strong>tree as current</li><li>Calls <strong>componentDidMount</strong> lifecycle method on nodes tagged with the <strong>Placement</strong> effect</li><li>Calls <strong>componentDidUpdate </strong>lifecycle method on nodes tagged with the <strong>Update</strong> effect</li></ul><p>After calling the pre-mutation method <strong>getSnapshotBeforeUpdate</strong>, React commits all the side-effects within a tree. It does it in two passes. The first pass performs all DOM (host) insertions, updates, deletions and ref unmounts. Then React assigns the <strong>finishedWork</strong> tree to the <strong>FiberRoot</strong> marking the <strong>workInProgress</strong> tree as the <strong>current </strong>tree. This is done after the first pass of the commit phase, so that the previous tree is still current during <strong>componentWillUnmount</strong>, but before the second pass, so that the finished work is current during <strong>componentDidMount/Update</strong>. In the second pass React calls all other lifecycle methods and ref callbacks. These methods are executed as a separate pass so that all placements, updates, and deletions in the entire tree have already been invoked.</p><p>Here’s the gist of the function that runs the steps described above:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/42eaa612c0249e10ec282d43a4d9148d/href">https://medium.com/media/42eaa612c0249e10ec282d43a4d9148d/href</a></iframe><p>Each of those sub-functions implements a loop that iterates over the list of effects and checks the type of effects. When it finds the effect pertaining to the function’s purpose, it applies it.</p><h4>Pre-mutation lifecycle methods</h4><p>Here is, for example, the code that iterates over an effects tree and checks if a node has the <strong>Snapshot </strong>effect:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f23c8556747ba1a718472b7f18e1f705/href">https://medium.com/media/f23c8556747ba1a718472b7f18e1f705/href</a></iframe><p>For a class component, this effect means calling the <strong>getSnapshotBeforeUpdate</strong> lifecycle method.</p><h4>DOM updates</h4><p><a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L376">commitAllHostEffects</a> is the function where React performs DOM updates. The function basically defines the type of operation that needs to be done for a node and executes it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e8869bb06a9e50607b2dc72374e129bf/href">https://medium.com/media/e8869bb06a9e50607b2dc72374e129bf/href</a></iframe><p>It’s interesting that React calls the <strong>componentWillUnmount </strong>method as part of the deletion process in the <strong>commitDeletion</strong> function.</p><h4>Post-mutation lifecycle methods</h4><p><a href="https://github.com/facebook/react/blob/95a313ec0b957f71798a69d8e83408f40e76765b/packages/react-reconciler/src/ReactFiberScheduler.js#L465">commitAllLifecycles</a> is the function where React calls all remaining lifecycle methods <strong>componentDidUpdate </strong>and <strong>componentDidMount</strong>.</p><p>We’re finally done. Let me know what you think about the article or ask questions in the comments. <strong>Check out the next article in the series </strong><a href="https://medium.com/react-in-depth/in-depth-explanation-of-state-and-props-update-in-react-51ab94563311"><strong>In-depth explanation of state and props update in React</strong></a><strong>. </strong>I have many more articles in the works providing in-depth explanation for scheduler, children reconciliation process and how effects list is built. I also have plans to create a video where I’ll show how to debug the application using this article as a basis.</p><h4><strong>For more insights follow me on </strong><a href="https://twitter.com/maxkoretskyi"><strong>Twitter</strong></a><strong> and on </strong><a href="https://medium.com/@maxim.koretskyi"><strong>Medium</strong></a><strong>. </strong>Thanks for reading! If you liked this article, hit that clap button below 👏. It means a lot to me and it helps other people see the story.</h4><figure><a href="https://react-grid.ag-grid.com/?utm_source=medium&amp;utm_medium=banner&amp;utm_campaign=reactcustom"><img alt="" src="https://cdn-images-1.medium.com/max/500/1*AqX3Hf4h2icjt8WkIuzv6A.png" /></a><figcaption>React Grid — the fastest and most feature-rich grid component from ag-Grid</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e1c04700ef6e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e">Inside Fiber: in-depth overview of the new reconciliation algorithm in React</a> was originally published in <a href="https://medium.com/react-in-depth">React In Depth</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>