 OK, I'll just take care of it. Thank you. I don't have a microphone, so if I'm not loud enough for people at the back, just let me know. And I'm also a little bit unrehearsed. But I'll do my best. Because I really like this topic, and I think that it might be helpful for other people. Oh, cool. This actually worked. All right, so we'll try this later on. OK, so I understand that we have half-reacted web people, half-reacted native people, and then some guests. Is that right? Yes. Something around that. So there's not a lot of knowledge that I can assume. But I assume that most of everyone here has used React before, but maybe hasn't dived into the internals of React. I have made a couple PRs and done a little bit of digging into it, but I can't claim to be an expert myself. But I think that every one of those talks that we talked about earlier is me just digging into the philosophy and just making into a talk as I go along. And so far, this is the most in-depth one. And when we're talking about possible topics, I think this is the one that I'm most excited about right now, because it really demystifies the framework if you can build it by yourself in 130 lines of code. And that's the promise that I'm making to you today. So we're going to build concurrent React from scratch. And the other thing is that React, actually, over the past two, three years, has changed paradigms completely from the stack reconciler to concurrent mode. It was completely invisible to you under the hood because you just kept writing the same components. But now, with the release of concurrent mode and suspense and time-sizing, you start to see the effects of it. So now it's actually the time to start digging into what the mental model is and why it's important. OK, so we're going to talk a little bit about a few different topics. React Fiber, linked list traversal, render versus commit. We're also going to clone a use state hook. That's just one of the hooks. Obviously, there's a lot more other hooks. But once you've done one, you can do a lot more. We're going to talk about what the work loop is, time-sizing and suspense. Just to get a sense, because I don't come here normally. How many people have actually looked into React Fiber? Like, seen Andrew Clark's repo and all that? Has anyone looked into React Fiber? OK, so completely new. OK, good. Good, this is the best intro in the world right now because it is the most accessible. I'm not trying to howl at it. A lot of people, they get too in-depth, right? And they are no longer able to explain to common people like us what React Fiber is. And I think if you want to do it, you need more accessible steps to get to that point. So I just want to give some shout-outs. I did not figure this out on my own. Most of this work comes from Rodrigo Pombo. That's the guy on the top, right? He wrote this project, Build Your Own React. He's been working on this for three years. And it's a simple step-by-step clone. But it's a very, very faithful clone. And it takes quite a few hours to understand it. So in order to dial it down, I have to incorporate some other ideas. In the middle, that's Andrew Clark from the React core team. And that's Lynn Clark at the bottom, who gave the first big talk about React Fiber. I recommend all of their work to understand if you want to go deeper. We'll start off with what a JSX element is. Everyone knows, should know, what a JSX element is. It's a plain old JavaScript object. It's just an object. It has two primary keys. There's actually a couple more. But those are the two primary ones, type and props. And it looks like this, right? This is very, very not alien to everyone here. Like, you have an object. You have a type. You have a props. And inside of them, you have the text child called Hello World. Obviously, we don't want to write that all day long. So we have a helper function called React.createElement. And obviously, it's a very short step from there to JSX, which is what we know and love. OK, so that's a JSX element. How do we flesh that out into a fiber? It really is a JSX element plus a whole bunch of stuff, right? So stuff in red is, you know, stuff in red are a unique property. It's like a link to a virtual DOM element. Hooks and effects for the kind of work that you want to do. We'll talk about this. We won't talk about this today, but you can ask me about it afterwards. The white stuff is linkless. So every fiber represents a node in your app, and it links to another fiber, and it links to another fiber. And it's bidirectionally links. It's more than bidirectional. It links to its own parent. It links to its immediate first child. And it links to its own siblings. So that data structure contains all the links you can possibly want to go up and down your app stack. I hope that's quite obvious after I explain it. OK, so let's write it. This is the part I should have, OK. OK, I already, let's see. OK, and sorry, let me just do some prep for this, because it's not super prepared. OK, so right now what I want, and I'm trying to resolve to do it bigger, so it's easier to see on screen. Last time I did this, I did it way too small, and only the front row could see, so that was really bad. So what I have here is a project. It only has index.html. It has Babel installed. Those are the only dependencies I have, just Babel. And it's got an index.html pointing to, with a root, and pointing to the source of that root over here. OK, I should not navigate randomly. Sorry, I don't know why I'm nervous I've done this before. OK, so the only thing I have here is styles.css. OK, that's just producing this very nice animated background. OK, so the first thing we're going to do is we're going to set up the globals that we're all going to draw upon for this project. So that's the basic setup. I have a utils file. Let me show the utils file quickly. Where's the utils file? Oh. It's not toggling out in one second. I think I may need to fork this. Just give me one second. Ah, it's not going too well. Fork Sandbox. OK, fork it on Sandbox. That makes sense. All right. OK, so we have a utils folder. And this folder only has about 130 lines of helper code. And it has simple things like reconcile children, create elements, create text element. And create element, you might expect, is just the helper function that creates types and props, exactly like you expect. Create text element, create DOM, commit deletion, and update DOM. So just 120 lines. I'm not extracting away much. But I'm just importing them into this app. And then I'm declaring a bunch of variables that we're going to use. So next unit of work, the current root fiber, the work in progress root. And we'll talk about toggling between the current root and the work in progress root and how that works. The deletions, work in progress fiber, and hook index. All of these, we're going to gloss over a little bit. And then we'll have a variable here called React. And that will be an object that has all the properties that we expect out of the normal React methods. OK, why am I so nervous? So that's the basic setup. And now we'll write our first fiber. So I've written a simple fiber over here. And what that is, oh, man. Why do I have a random host component thing over here? OK, hang on. I think I need to comment this out. I think I pasted the wrong thing over here. I'm working in progress root. OK, so this is the structure of a basic fiber, but we don't need any of this. So I'm just going to comment it out. All right, so like I said, a fiber is basically that same JSX element, but with all the other relevant tag stuff. We don't really need that. You know what? I'm just going to explain that the fiber is not something that we need over here. And so I'm going to set up a work in progress root fiber. So this has a link to two things. So document.getElementByD. So this is a real DOM node. I'm going to stick it on the DOM property of the work in progress root fiber. And then I'm going to have a JSX element, and then I'm going to stick that as the first child of that of the element. And these are just reminders to self that these are all links to other fibers that you could have in the future that is in the data structure of a fiber, but you don't really need it right now. So bare minimum fiber looks exactly like a JSX element. Makes sense. OK, let's get something to show up on screen. Over here, I'm using JSX to display Hello World. Let's actually try and render it. So I have a function for a simple render. And a simple render function basically does this. It takes an element and a container. And based on whatever element type, it creates those DOM nodes using a DOM APIs. It goes through every single property and then attaches it to that DOM as an attribute or a prop. And then it renders it out and appends child to the container. This is all standard vanilla JavaScript that you would write yourself if you were making an app. And so part of the framework is to extract this away from you. Now I have a render function, and I can render whatever I like, from an H1 to like a div with maybe like a UL in there. It'll become more relevant why I'm doing this later on. Sharpie. Is it 1P or 2P? It's 1P. Oops. I'm learning, OK. I'm learning. I'm sure Ronaldo doesn't know that it's 1P or 2P. Anyway, so hopefully everything is super, super clear. I want to go slow in this beginning part because I lost people last time, right? So I really want to, like, we have a work in progress root fiber. So we have this JSX element, right? We stick it in a work in progress root fiber, which contains this is a prop in this container. Then we pass it into a render function that says we render the element and the container itself, and that's all showing up on screen there. Very, very clear, right? OK, so that's the base part that we have to start talking about, what is rendering in React. And I'm just mostly going to stay in this mode so that I can quickly toggle back and forth. So a very naive way of rendering, right now what we're doing is we're starting at the top of this div, and then we're saying let's render everything all at one shot, right? Let's find if the app is small. Let's see what happens as we go along. So this is render and commit, OK? Not an official term, but I think it's very, very easy. It's much easier to explain in contrast to what I'm about to explain afterwards. So render and commit. We start at the root, and we do work, and then we save it to a DOM. So those are the emojis that I chose, right? Work and save. Then we go to the div. We do work. We have that rendering function worked out, and we save it to the DOM immediately. Work, save. Work, save. And at this point, if I come along as a user, there's a chance I may see what this is. I mean, there's different terms for this. You can call it inconsistent state, or you can call it tearing if you borrow the game development analogy. But basically, half the app is updated, and half the app is not, right? So that's not a good experience for your users. Anyway, let's keep going. Do work, and save, do work, and save. And then once you're done, and that's commit and render. Every single step, you commit and render along the way. So obviously, you can do a little bit better. And the way that React has done this for a long time, and it's not even anything to do with Concurrent React, it's a render then commit mental model. So the way you want to think about it is that we have that work function, and it's attached to the work in progress root fiber. By the way, in my code, I'm going to call this perform unit of work, but don't really worry about that. And we're going to follow this traversal algorithm, right? So you go from the div down to the first child. We do the work. We're not saving. We're not committing to a DOM. Then we keep doing the work. We're not saving. We're not committing to a DOM. Do the work, do the work. And this algorithm is very much prescribed. This is the linkless traversal algorithm in React. I have a link for you to learn more about it later. So if there's a first child, you go to the first child. If there's no first child, then you go to a sibling. If there's no, and then from the sibling, if there's a first child, go to first child. If there's a sibling, you go to the sibling. And then if no child, no sibling, you recurse all the way back up. Does that make sense? So that's a very sort of deterministic way of traversing your entire app. And the whole idea is that we'll do all the work in one shot, but not commit it. And only once we've done all the rendering work, which is running your code, like your set state, whatever, once we've done that code, then we transfer it over to the current root and commit it to the DOM. So in that sense, you have a very clean cut over from old state to new state and no tearing in between. For React, that is very, very essential. And in fact, there's a core goal of concurrent React and time slicing in particular. OK, so if you want to learn more about traversal, Sebastian Mark-Werger, he actually wrote about this three years ago, just like in sketching out what the fiber architecture looks like. So if you go to the React repo and look for issue 7.942, you can find it there. OK, so that's linkedless traversal. We don't even need to really do any. OK, so we have a simple render, but this rendering does the rendering work, right? And then it also commits at the end. This append child is the committing. And it does it per node. So we need to refactor this a bit to actually do a more realistic render. So from this simple render, I'm going to kick out the render. And then I'm going to do a more complex render. And I call this the fiber render in my work. It's a little bit more work. But if I reduce it to this, it makes a little bit more sense. OK, so we're going to perform unit of work. So this is the core of it. We're going to start off with an object called next unit of work. We're going to, at the beginning, we'll sign it at the root. We start at the root, right? And then while there is a next unit of work, we'll just infinite loop until it's done. OK, so next unit of work, then we have this function called perform unit of work. It does, it performs the rendering function on the next unit of work, which is currently the work in progress root. But it returns the next node, right? And then you assign it. And then you perform it again on itself. And it just loops all the way through until you loop through the entire app, like we talked about. Then you commit the work. So that's encapsulated in these two functions over here, which I'm purposefully sort of occluding for you. But just to show a little bit, it does the reconciled children work that I've imported from my utility library. That's the rough idea. I really want to stay high level, right? Because this is a lot to get through in a single talk. And then we also do the commit work thing. And remember, we only do a commit work at the end. Commit work basically just does the append child, update DOM, or delete child functionality. So within this 78 line piece, we already have something more or less working. I think I should comment this out. So I always want to show you, at what point do we have working code? At what point do we have partially broken code? So at every step of this point is a workable framework, but it adds more and more features. What's the feature that we've added? We've added nothing, actually. We just evolved our rendering function to split it up in that order that we talked about earlier. Render, then commit. OK, so an app that just does this, not very helpful. We need some interactivity. So then we will introduce this concept of a work loop. And when I was first told about this, I was very shocked because you're supposed to avoid infinite loops in your code. But surprise, there's an infinite loop in React. And that's the work loop. And it's similar to basically any operating system, any game engine, that there is an infinite loop somewhere in there and there's driving everything. That's really the core of the framework, which is you register all these callbacks, and then the game loop just decides when to call your callbacks. So that's the rough principle for why do a work loop. And the reason why we need one is because this work is only done once. You start at the working progress route, do all this, commit to the DOM. And then that's it. You need to loop it again. So I'm going to delete this and show you the work loop code. And so this is the work loop code over here. I hope this is right. Let me see. Work loop, work loop. I think I need to call it. Did I put it in myself? So request a callback work loop. So it's not running right now. I don't really know why. But I think I did remove the renderer. No, I haven't implement. I removed the simple render function. But I haven't introduced it just yet. OK, don't worry about it because I'll probably reformat this in a bit. Wait. Yeah, render is not defined. Why is render, where do I use render? Yeah, I can clear console. Let me just refresh this. Live coding fail. OK, so if anyone spots anything, you get a gold star. So is there some way to introduce it? I should probably use the current route. That's right. No, actually no. It's unused. OK, don't worry about it. I'm sure I'll figure it out later on. But the main thing I wanted to talk to you about is that is that OK, sorry, that really threw me for a loop because that's supposed to be working code. The main thing I want to talk to you about is this work loop. What have we done? We took that same loop of do work and then iterate through the entire app and then commit the work. We took that same loop and then we stuck it inside this function and then we did this recursive thing. So we call it one time and then at the end of the function call, we call ourselves again a second time. So that's the infinite loop there. We're using this unfamiliar API called Request I Don't Call Back. Most people will not have used it. Just think of it as set timeout with a slightly different API. So over here, the internet is very slow. OK, fine. Oh. This is called state tearing. It should not render. Yeah, I should be on Swapy's internet. Swapy A. Yeah. OK. I don't know. Anyway, it doesn't matter. Just think of it as a set timeout. And the main thing that it gives you is a deadline. So for example, if you're trying to render 60 frames per second, every second is 1,000 milliseconds. 1,000 divided by 60 is 16.6 milliseconds. So in that 60.6 millisecond window, you have the ability to do as much work as you can. And the goal is to use that to yield back to the browser so that it can take in other inputs like clicks and typing and all that. So your app feels more responsive. Unfortunately, right now, we have this infinite loop. We have this non-stop loop. It just says while and then, bam, just goes through the entire app. So we need to break it out a little bit. So let's implement time-sizing. So we'll have a simple little Boolean called shouldYield. And we'll say false. And then we'll take this deadline API and we'll just say deadline.timeRemaining less than 1. So deadline.timeRemaining is the DOM API's way of telling you how much time do you have left before I need it back so that I can do my browser stuff. So we'll just say if it's less than 1, we'll say we should yield. If it's more than 1, you can keep doing your work. So let's implement this shouldYield. Basically, while next you know work is truthy and shouldYield is false, something like that. And that's a very simple implementation of time-sizing. There's a question over there. I think, actually, the next thing of work will be assigned to work is progress. That's why there's nothing more. Yeah, you think I did that? There's a chance. Yay. Well done. Go, Star. Go, Star. Basically, what happened was my, actually, so I've given this talk before and I had the presentation. It worked on. It went fine the last time. But then my hard drive crashed. So I had to recreate all the copy-pasting stuff today. So yeah, sorry. But good catch. Yeah, and in fact, we'll take this fact later on to do the hoax stuff. Because the whole idea is that you have this infinite loop and whenever you want to do work, just pop it onto the thing called next you know work and the rendering engine will take care of it for you. Because we have this infinite loop, it's constantly checking if next you know work is truthy. OK, so that's good. And so now we've implemented time-sizing. And this is not theoretical. Like this is a real, real thing in your app right now. If you switch to concurrent mode, there's a strong possibility that you see some more interactivity because of the time-sizing. So this is an image from Andrew Clark where he was showing how you start in synchronous mode, you start doing this rendering work. And you do it all the way through your entire app. And then you commit to the DOM. That's how React used to work in the Stack Reconciler mode. In the Fiber Reconciler, we're breaking it up every however long you want. The reason you use request out of callback is because based on your device, on your mobile phone, or something, you might want something less than 60 frames per second. But the whole idea is that whatever the window is, you're doing your work within the window. You yield back to the browser, let the browser do its thing, and then you continue doing your work. And only after you're done doing the whole thing, then you commit. Same principle in both cases, but here you're chopping up the work. And it makes your app a lot more responsive. This isn't just theoretical. You can actually implement, toggle your app back and forth. An expensive app, take something that's kind of chunky and laggy. If the rendering is super expensive, you can actually see it in your DevTools. If you turn on concurrent mode, and you can see it chopping up inside of your Flame Profiler, whatever you call it. Is it Flame Profiling? It's a, yeah. I don't, honestly, I just don't have this scale of app to really test it on. But yeah, I mean, it's absolutely there if you need it. OK, so that's time-sizing. Now let's actually talk about a hook. Because some interactivity is needed. And the way we're going to implement a hook is just another function. So I'm just going to implement, I'm just going to paste in this function. This one is most related to the one, the talk I did previously, the previous time I came here. And basically, it's a function that replicates the hook API. So you have a set state, and then you have a hook.state over here. And then you return that as an object. So as a consumer, you just call your use state and get this out. The primary thing, what is this linting error? OK. Ah, oh, another bonus point. Anyone knows what this is? Optional chaining. Optional chaining, yeah. So I'm using this just because it's in a standard now. So we can all use it with abandon. It just makes your code a lot nicer. Like I would have to do a lot of n, n in there. OK, so the main thing we should take note of is inside of this set state thing, which is exactly right, whoever that was who helped me out just now. In order to set state, we're not calling like some react.render again. React render is running already. And there's an infinite loop. Instead, we're just chucking something onto the work in progress route and then put it into the next unit of work. And let react pick it up whenever it's ready. And that's how you schedule a set state. And this is the primary thing why react is not reactive. React is not reacting to your user input. You're only scheduling a state update. And that's why everything is async there. So a lot of beginners will trip up on that if they're not careful. OK, so let's actually use use state in our app. I think I have a basic little app prepared. OK, basic app here. And then I'm going to delete the old app. Again, I screwed something up. Let's see what I screwed up. OK, and then I need to expose it on the react object over here. OK, yay! Nice. OK, thank you. I always do this. So every one of my talks, I'm always creating a framework from scratch. And then I always end at, let's do a clicker, and then everyone claps, and then I go home. But let's do something more ambitious, right? So now we've proven that this looks exactly like a normal react app that you write on a day-to-day basis. And we've cloned every single thing from the bottom up. And so far, we've only taken 120 lines of code. That's good, not good enough. Let's keep going. So oh, React is also changing in terms of its render API, right? So we actually haven't even written a render function. I'm actually a little bit apologetic about that. Yeah, so we have this Work in Progress root function over here. It's not very nice. We should actually have something nicer. The way that we really want to write our apps is using this render, like react dom.render or something, right? Render element container, whatever. So let's see if we have a render function here. And so we're just taking this Work in Progress root thing, and we're just sticking it inside of a function. And then we'll call render element container. Let's actually put it next to each other like that. So same deal. It's just that now we have a function to do this, so we don't see the ugly part. And again, this is the kind of code that we write, react dom.render element in the container. But in concurrent React, we're actually changing the API a little bit to a create root API because you can have multiple roots. So the API is pretty, it's just like a small difference. So I'm just going to say create root, change this to create root. It takes the container, and it returns an object with a render method, which has that element in there. And then I'm going to cut this case here, and now I can say create root.container, and an element again. Think that should work. Did I screw that up again? Huh? Oh, yeah, good try. This is so much worse than last time. Okay, yeah, yeah, okay, that works. Thank you very much. In fact, I'm going to expose it on the React object as well. Okay, so yeah, so that's the create root API. It's slightly different just because they wanted you to have more options when you're creating roots, but just don't worry about that. Just when you move to concurrent mode, this is the kind of thing that you need to take note of. Very, very small changes. Okay, so in the last bit, we're going to talk a little bit about suspense because at this point, we have a fully functioning React clone. And we'll just talk a little bit about how you can take this mental model and tweak it to understand new things that are coming up. Okay, so first of all, I'm going to extract everything that we've done so far into a standalone file because this is getting a bit long. We're going to call it react.js because why not? Okay, I'm going to cut, paste, take this as well, and paste over here and export here. Hopefully that, like, oh, I need to take this as well. Okay, that looks like I got everything. And then I can import React from react.js, whatever. Let's see it work. Ah, where did my thing go? Wait, wait, wait. Does anyone know what's code sandbox one after view? Wait, where is it? Where did it go? Toggle preview. Where did it go? Did I just refresh? Yeah, I'm going to save it and I'm going to refresh it. When in doubt, just restart. Of course, right? Okay, so, but like now it's very, very convincing. Now it's like very scary how close it looks. Look at this, it's pretty nuts. Okay, so let's talk about suspense. So, okay, I'm going to poll the audience again. Who here has at least, has an inkling of what suspense is? Has tried out suspense? Nobody? Okay, about like five people. Okay, so suspense is a way, so how do you fetch data in a hoax world? You have to, you have to, sorry, how do you fetch data in a hoax world, right? There's no component did mount or something or, I mean, you can do event handlers for sure. But typically you have to stick it inside of a react.use effect and then maybe you need a ref or you need to memorize or you do some other BS to actually do that async effect and then resolve it in a set state, yeah? So those of you who are familiar with hoax and familiar with doing any sort of, like the equivalent of this would be an event handler or component did mount or some sort of life cycle in the class, react class component world. React suspense is a more declarative way. This is very imperative. Like do this, then do this, then do this. React suspense is more declarative way of saying, here's a resource and then go fetch it and React will figure out the promise resolution for you. So the whole idea would be something like this. So I have here an API that basically fetches from a serverless function. I work in LFI, so I set up this function by myself. And basically I can just show you what it does because last time I didn't do that and people were kind of lost. This function only does one thing, which is you give it a number and it gives you a number of images back, right? So I have here one, two, okay, three, okay, four. So like basically a very, very simple API, right? You're just like toggling the query param and it gives you a different response back, okay? So over here, so that's a simple fetcher function and then it does some post-processing, not really important. But what happens, what's important is over here. The way that React wants you to work with suspense is you wrap it in a resource. And this is kind of how it does. So you pass it a promise to resolve. And then it tracks whether it's resolved or it's been resolved with success or resolved in an error or it's still pending. If it's still pending, it's gonna tell React so that it doesn't transition the whole thing yet. Okay, so, and then we'll wrap it in this create resource API. That's just something that's standard if you go look at the docs for React suspense. Okay, so we're going to import that. I think we can get rid of this. So, where is my dog app? Okay, I think this works. Oh, this doesn't work. Okay, so why? Because the main way that, so you can see that it's actually very simple to, we're just creating a resource from our API. Remember it's just wrapping that fetch function, right? And then we're just reading from it. We're not saying like go to fetch and then use effect and then set state or do something with component dismount. You're just reading from it as declaratively as you read from hook state, right? And in your code, you can just use that as a, you get back an array and then you can do docs.map and then you map it onto an image just like you would do normal code. As though you were reading from memory, but you're not reading from memory. You're actually doing an API fetch and that's all extracted behind inside of there. It's just a much simpler API and it manages the transitions well for you as well. But we haven't implemented React suspense yet. That's why nothing's showing up. So the last part of this talk is about how do I explain that? Okay, so inside of this promise, the way that we actually resolve this promise is we actually throw the promise up. So we are past a suspender function and that's the function is just this fetch dogs function. It's this suspender function that wraps the promise over here. We're past it here and we throw it upwards and we expect React to catch it and then render it. And then resolve it for us. And once it's resolved, it re-renders itself to the resolve state. So in order to do that, we need to actually build that functionality into React itself. So where are we gonna do it over here, right? And for me, I think the best way that I figured out how to do it was to catch this performing in a work. So performing in a work is where everything inside of there is where you're doing your app code, right? So if I add a try, catch around this, it should work. Which means that any error coming out of this, right? It's either a promise or it's not a promise, right? So if type of error, actually I'm gonna use instance of promise. So if the errors is made from a promise, then resolve it. If not, okay, I just locked myself into an infinite loop. It's choking a little bit. Okay, stop. How do I kill this? It's not saved. Don't worry, don't worry. This is the fun of live coding. I mean, honestly, we're covering less content as we live code, but yes, that's probably what a smarter person than me would do. Right. Okay, here. So we don't need syntax, I think it's fine. But we'll just say if it's a promise, we'll have, we'll say error.then, then we'll actually resolve it by doing some other work. I don't think we actually need to do anything else apart from that. But, and then if it's not a promise, we'll just actually rethrow the error, right? We just keep throwing it out. Just say it's not your IT. Okay, so over here, I think we are done. Did I screw something up? Else, I'll just break it. Close else. Oh, yay. Okay, yay. So we're fetching dollars from the API. Oh, except that I'm not setting state properly. So over here, once the promise has resolved, we actually need to tell React to reschedule again. And we already know how to do that, right? We actually can, we actually, we did the same thing in the use state hook by just setting the working progress route and the next, you know, work. So I think I can just do that by saying next, you know, again, this is not by the book proper way to do it, but you're just scheduling another round of rendering again. So once this resolving is done, I think, please show up. I actually, so working progress route is also cleared. So I'm also gonna do this. Where is it? Because working progress route will be run into as now. Huh. Okay. Can I kill this somehow? Pretend it's not there. Okay. I thought, I think, I think, I think I did. Okay. So I do have a backup. Don't worry. This, this is for precisely this reason. Suspense work loop. Okay. Let's actually look at what my code was supposed to do. Okay. Oh, right, right, right, right, right. Okay. So, sorry about that. Okay. So I was, I was, when you, when you actually, when you actually have an error that you throw, right, you're supposed to suspend the work. So I actually introduced a variable over here to keep that suspended work. So I'll just say, like, while I'm resolving this, like, choke first, and then, and then, and then go and resolve it. Once it's resolved, then you dot then on, on the promise, right? And then, and then you, you schedule that new, new, new, new round of work to be done. And you, you set the suspended work back to the next, you know, work again. So you continue rendering where it left off, right? It's the whole pause and resume process again, just it's, it's, which is very fundamental part of fiber. And now I'm screwed. Okay. Okay. All right. So, but, but you get the idea that, that we were able to modify, like once you have a good mental model, you know exactly where to go to, to, to, to implement new features, to understand new features, even though this is not, this is nothing like the real code, right? But you understand the real features so that when you actually write apps like this, you understand fully what's going on under the hood and you're a better user of React for, for that. Okay. So I'm just going to leave off with what else we didn't, what else we covered and what, what we did not cover. So we covered today, fiber, linkless traversal, render versus commit, use state hook, the workload, time sizing, and with a lot of difficulty, some suspense. But, but you get the idea that this is all doable by human, by multiple human beings like, like you and me. And, but there's also other stuff though, like there's always this question of like, okay, if you can write all that by yourself, why use React? And it's all this stuff, right? So the stuff that you, like if you wanted to, you can keep quoting, but you, you probably just end up with the React code base itself. So, so feel free to be my guest. One of the new hooks with suspense that sort of tap into the suspense state and the scheduler underlined this whole thing because React doesn't actually use, require a set of callback. It uses a scheduler library that is meant to be shared with other libraries. And so this, these are ways to tap into the scheduler function alongside with the regular hooks that you already, you should already know. So yeah, this, this is all that, this is what's missing in React. This was in React is missing from this talk, but hopefully you get a better understanding of the mental model. And thanks very much. Questions? The way RK takes questions is we pass around quickly. Where's the, where's the lab? Press class two. Class two. Can you please go back to the code where we have the suspense? Like, yeah, suspended work. So, I'm just wondering what happens if, let's say a suspended work got expired because something else happened during that time period. And then you resume the work with that, would there be any conflict or? Yeah, so the official answer is that there is actually a queue of effects and React will always, is think of it exactly like it. When there's, when there's a, when there's like a git commit and one after the other, React will always apply them in order. So while there's suspense going on and there's work to be done, it will not commit to the DOM. It will just hold that state update that you scheduled in memory or, let's say it's a higher priority, it will actually render that first. And then it will resolve that promise and then re-render with the work that we did over there. So it's always in sequence and it will show on. So React has a, has an idea of what the queue is and React will and, but what it shows on screen is based on priority. So there's a concept of a priority queue, like there's five different levels of priority in React. So if there's something that's high priority, that will show, there will flush the screen first. But when you apply something lower priority and that gets resolved, that will be resolved, there'll be, your whole app will be rerun again, the whole thing. And then the final output will be flushed to the screen as well. So whatever conflicts, like the whole model of React is meant to declarative, like everything's declarative here, right? And that's why it's so much easier to think about because when in doubt, just rerun again. So once you have that two conflicting, I mean, it's not conflicting, it's like it's just different states that are being set, right? And you don't know how they resolve it towards the end. So just rerun the whole render again, which is why like one of the reasons for moving through hooks and away from class, the class-based lifecycle model, is because they don't want to promise you that like we'll only run component did mount once. They don't want you to do that. They may rerun, they may stop rerun or just rerender again because something else up the tree updated multiple times. And you may not be in control inside of the component. So they don't want you to tie it to the component instance that much. I just make sure, just to make sure I understand it correctly. So we are saying that let's say we click to get a dot picture and it's fetching and the user decided to switch to another tab, maybe, and showing that it's higher, let's assume it's higher priority. The switching of the tab. Yes, the switching of the tab. And then you show the right wheel, wheel, wheel, wheel, wheel commit the work and the screen that is playing another tab. And after this being that tab, the dot picture, right. So they will actually rerun the whole thing to make sure that everything is correct. Yes, so if you think about what happened in sequence is you send the fetch, right? And then you send the switching of the tab. But over on the rendering side, like the switching of the tab will always take priority because that's a high level visual element. So nothing, so the dot promise, because promise are not cancelable normally, that will still resolve, but it just won't show up. It won't show up. Right, because you already, like the more important thing is that every single time I'm re-rendering the app from scratch and you said, and over here there's a router that says like, all right, tab two now. I only show tab two. So the tab one with the image doesn't show. It is, yeah it is, not shown, but... The promise will still resolve. Yeah, since I already registered the resorbing, but still it will trigger a react to at least this moment. Or... No, yeah, it will just be not. Yeah, good question. Actually it's like for example with the data that changes it to implement the data cache, right? Yeah, so we have a very simple cache over here. Where? Uh... So the cache is just this arc. So this is like a last, whatever was last called is the cache thing. So it's like a, what do you call it? Memoize one effect. So I just store it inside of current arg. If current arg is different, then I'm just invalidating the cache and going fetch the other one. But obviously you can have a deeper cache than that. In fact, I think there's an interesting case to be made to put this cache inside of service workers. Yeah, cause then your app just loads instantly, right? With all the cache that you've done before. My question is that, actually this one should work in current red version right now. The only one missing is that good implementation of the cache, right? Yes. Yeah, so... I think you try something like this in any production application. Because I don't dare to... Yeah, so right now the status is that it's still experimental. So you go react.js.org slash current. It's still experimental. So they have not pushed it and they have not sort of marked it as production ready for most people. But they have been using it in production at Facebook for a year. So it's up to you what you want to do. I remember that one and a half years ago when I first listened to the talk from Dan in the React Island or something. They introduced that and they promised that, okay, this one will be the future. And actually it's one month and one year and eight months already since that day. Yeah. Yeah. Yeah. I gave up that idea. So the main thing, the interesting thing is that, I mean, you know, who among us has not estimated and then been way off? So I don't knock them for that at all. The main thing that they're, like what I presented to you is entirely client side. And the main thing they're focused on is actually the server side story. How do you server fetch and then stream it down to the user and hydrate in an intelligent fashion that doesn't screw up your state? So that's, they've been working on that. In fact, probably more than the rest of these details. Like they could probably back this up if they want to, but it's not, it doesn't matter if the server side rendering story is not fetched out for them. I have a, I mean, I even show this to you, like this you cannot do. Like, so he, so he just, so then just, till it this out recently. So there's a, this is, this is hydration. So people, hopefully people know about server side rendering. Like you render on a server, you send HTML and then you send the JS and then you hydrate into a full SPA. Yeah. Okay, so over here, this is, this is the idea for suspense enabled hydration, right? Where you're, where you're, there's no JS loaded. So you, whatever buttons you have, HTML you have is not interactive. And then you manually load the JS and that just immediately gets hydrated with the sequence of, of events that you already, that you already did. So, and you can chunk your, you can chunk your JS up, so you can load these separately. So if the user never uses your nav or your sidebar or something, it never loads your JS. And you only load the stuff that is being used. So that's the, that's, okay, so this is fine, right? This is like, okay, impressive, whatever. You can do that in normal JS, but you cannot do this unless you have a complex enough runtime. So that thing, that question just now about applying that sequence of events and having, having that queue in mind, let's you be able to do this. So we're clicking multiple things and click, click, click, click, click. So, so these states might have interaction effects, right? And you don't really know, like, so, so we'll just refuse to show until you load both JSs and then, and then the clicks will be registered on both. So it's like, if the, if the required dependencies all down the chain are not resolved yet, we'll just never show, we'll just never show it. But if they're all resolved, then we'll show all at once and it'll be consistent state drop. That makes sense. So like, the whole idea is that you as an app author, you only declare the intentional screens that you want to show and all the, all the unintentional loading states in between will be managed by React. Not by your, I mean, previously it was, it was managed by your code. You, you will be like, you use like, I don't know, React async or component amount or React loadable is another very popular library. But this is all now being absorbed into the framework. Guess one more question, everyone? I'll put this on the, on the GitHub thing, but hopefully it doesn't scare people off too much that, like, yeah, I messed up the coding but I'm speaking as I code. So a little bit messy, but the amount that we just looked at was 133 lines of code today. Nothing, nothing. But hopefully it gives you, like, this is the best place to start studying for a better mental model of React. Okay, cool. Thank you. Thank you.