useWat with David Khourshid === [00:00:00] Hi, and welcome to PodRocket, a web development podcast brought to you by LogRocket. LogRocket helps software teams improve user experience with session replay, error tracking, and product analytics. Try it free at logrocket. com today. I'm Tejas Kumar, and today we have David Khurshid, a dear friend of mine. We've had the privilege of speaking together at multiple conferences, Um, but today David's here to talk to us about his talk. Use what from this year's react rally conference. I indeed had the privilege of watching this talk and it was. One of the best talks there, but today we're going to dive into use what we're going to talk about react. We're going to talk about use effect and use memo and all of the details in between. And with that, I'm so excited, David. Welcome. Thanks for having me and great talking to you. Yeah it's always a pleasure. You're one of my favorite people to talk to all the time. Unfortunately, on a podcast, I can't be as ridiculous as I am in person, but. But we'll make the most of it. David, let's talk about use what? The talk was a big troll, if you don't mind me saying. And the name gives it away. Could you dive into just even the term use what? Where does it [00:01:00] come from? What inspired that? Back in I want to say 2012, or it was just many years back, there was a talk by Gary Bernard. It was a lightning talk called what I think it was just called what, and the purpose of that talk was basically to showcase how JavaScript is a little bit ridiculous at times. It was, doing that classic, Hey, if you add two decimals, guess what happens, and if you add, not a numbers, a lot of times you get, and then, and then that Batman or, just silly things like that, and it was accompanied by Watts images, which you know I didn't. Want to include too many of those just because I don't like using too many memes in my presentation. But I felt like React was way overdue for a similar talk. And I just wanted to have a humorous talk about just how weird Reacts could be, but my main point in the talk wasn't to poke fun at React and say, Oh yeah, this is how silly this framework is. But mainly to say Hey, all frameworks. At the end of the day have their idiosyncrasies, they're a little bit weird, but we [00:02:00] work through them and we could still be super productive with them. And we just have to realize that this is the reality of the programming language we're working in, the environments that we're working in, we have to deal with some weird stuff and it's just fun to, to see how weird things can really get when working with Reactor or any framework for that matter. Yeah, I appreciate that. Do you mind sharing again the name of the author or the speaker for the previous talk that inspired this? Sure. And I hope this is right. It's Gary Bernhardt. Bernardz. Okay, we'll have to put a link to that in the show note captions and I have to watch that because I think conferences need more content like that. I feel like sometimes we take ourselves way too seriously talking about use client and use server and server, like the latest thing is server actions and oh my gosh, we're back to PHP and all this. But if we zoom out of the jokes and the memes. What we're ultimately doing is building web experiences that are fast and that service a great amount of people, right? And I think it's work that yes, we should take seriously, but I think when we take it too seriously, we lose sight of the real [00:03:00] beauty of the things we enable. Like for example, like I, I book a lot of travel and most airline booking systems suck. They just really do. They're not accessible. They take a long time to load. And for those of us who use things like React and server actions, whatever it may be I like to think we're creating a better world. And we sometimes need that fun is what I'm trying to say. I'm curious you've been somewhat critical of React on social media. One, I think that's positive and that it helps us think and improve the library. Not me, but I feel like the community. How do you actually feel about React? so I feel, if we were to compare framework versus framework or language versus language is reacts the fastest framework? No, absolutely not. And I even joke in my presentation that reacts not even the fastest reacts framework, It's not reactive. Is it the easiest framework to learn? I would also say probably no, like there's easier frameworks to learn. But what react really excels at is just getting [00:04:00] things done. You have a huge ecosystem in a huge community and. Sure, that ecosystem can, include lots of packages that are poorly maintained or do things in a sort of funny way. But the point is that if you need to get something done, you can, basically throw a stick and hit someone who knows React especially in the community. And there's going to be someone or, like thousands of people who have run into your exact same problem or use case. And you're able to use that knowledge and just build whatever you want. So I would say that's why React is basically my favorite framework for just getting things done. And we could talk all day about Oh, how about the performance optimizing for that's the bundle size, et cetera. But at the end of the day, your job as a developer is to get things out to users and make things valuable for them. React is great at that. We use React, we use Next. js. I live, eat, and breathe React every single day. You know, What's really interesting is React is just wildly popular, despite the fact that it is not even the [00:05:00] fastest React framework, as you put it. But every single time I post on social media about React, I just get a much larger response than if I just do like JavaScript. And it's not just that, like I know a bunch of conference organizers and when they organize JavaScript Belgium it gets a third of the response as react to Belgium, like you just slap react on something and it just takes off. I don't know why some conspiracy theorists tell me that it's because meta like biased the social curve towards react. I don't know. But you mentioned a number of hooks in your talk. In fact, I believe in one of the slides you went off screen because there were so many. Let's talk about those. Because I feel first of all, do we know off the top of our head? And I'm sorry to put you on the spot. Feel free to not answer how many hooks there are out of React at the current time. I believe it's about 20. And the only reason I know that, I don't know if that's the exact number, but the only reason I know that's an approximate number is I recently made a meme where I had to put a bunch of [00:06:00] hooks and rank them. And of course I ranked use imperative handle as the best hook ever. Okay. Let's get into that. What makes it so good, I'm, I'm just kidding. I've actually almost never used impaired use imperative handle. But it just seems like a really safe, escape hatch for working with working with refs. But of course it's one of those hooks where you're absolutely never going to need it unless you're a framework author. So the joke is that, it's really not a useful hook at all, unless you really need it. but what does it do? So use imperative handle is a way of handling reps imperatively. So just sounds like a tautology, but it provides you an interface where it's like, Hey, instead of me giving you the raw rep, I'm just gonna give you these methods that you could work with. And so that's what you get. That's your interface. I'm going to protect the rest of my inner workings of my components. And that's what you could do. You can make a ref where it's yeah, you could play and pause. And if you want to provide that to anyone asking for the ref, then you use imperative [00:07:00] handle. Again, I might be getting a couple of these things wrong because it's been such a long time since I read the docs on Yeah. I recently dove into use insertion effect, which I think is pretty cool. Cause it's, I think the biggest cases for CSS and JS. Style of insertion of style tags, where you do it in a safer, arguably more performant way. Can we talk about your actual favorite hook? One that you feel like developers don't use enough that provides tremendous value. I have one. This is why I'm curious about yours. so I have two, but The one that I feel that developers should use a little bit more is use reducer. And that's because like I joke about in the talk, people tend to go from use states to use eights where they have eight or more use states all over the place. And all of it, it's like use states is really good for when you have one piece of data, it's living on its own. And that's the only thing you really want to manage just a bit of information. But then. If you have eight different pieces of data that are all related to each other and you find yourself having to orchestrate in the [00:08:00] components, event handlers Oh yeah, when this happens and set the state of this and set the state of that. And if this is true and this is this value and set the state of something else, it's like you're really editing one object, but that object is being spread among so many different use states. So just. Use a reducer. People are scared of it because it introduces indirection. They're afraid of switch, case statements. It's really not that bad. And honestly, you could use reducer very much like you use date. In fact, you could, because that second argument, the dispatch thing, that doesn't have to be an event. That could be a, hey, I just want to give you... A partially updated object, and then you fill in the rest, maybe do some validation, maybe massage the data a little bit, whatever you want. So useReducer is actually a lot more flexible than people think. Would there be an intermediary step here that developers can benefit from where, and if you go from use eight, use states instead of that. From straight to a reducer, could you go from reducing, fun intended, your eight use states into [00:09:00] use state of one object and then just update that object? Yeah, and I've seen that a lot, where you know, you could set the states and then have a function taking what's my current state, and let's spread that and then add partially the next state. But at that point... Uh, You're sort of reinventing useReducer, or like what you would do in useReducer anyway. And you don't have safety, because let's say that you have a thousand line component file, and in one place you're like, okay, I know how to use my mega useDate. I just, get the current value, spread it on, and then add my partial value. But then let's say another developer on your team comes on, goes way to the bottom of the file, and is hey, I really need to change this date. So they just completely wipe it away. And it's like, wait a minute. There's no safety guard that says you can only set the states to these constrained values. That's the benefit of useReducer. It gives you that layer of protection. Is there maybe a lint plugin or lint rule that will detect two or three subsequent use states and go yeah, you need to turn this into a reducer? That would be great. And now I really you're nerd [00:10:00] sniping me because I really want to make that, Yeah. uh, But I have no time to do that. I'll either make it. and invite you as a collaborator or we can make it together or something because that do. there's even probably a fixed flag where it will rewrite your use states to some type of reducer logic or Yeah. Or use copilot, say, Hey, combine my use states. If open AI is working, it was down today. It's It's a free open source project idea there. Okay. So you mentioned use reducer. Just because I did tease that I have a favorite hook. My favorite hook is. By far use transition. I've been writing a chapter on concurrent react and like the idea that you could put anything in a transition and you could put literally anything and start transition, the most expensive state update in the world and react will start rendering this thing. Somewhere off screen and when it's finished, commit it. And in the meantime, you get it is pending. So you can like show a spinner. That's tremendous. It allows UI to feel so snappy in cases where it wouldn't. Interesting. All right. So at [00:11:00] Stately AI, it's basically a large canvas based tool for creating, just state machine and state chart diagrams. And we have been running into people who have been making state machines with hundreds of states and transitions, and things get slow. And so I remember a while back, I was asking Mateusz Andrus online, I was saying, hey, all of these, Concurrent ish features. I know they're not calling it concurrent mode anymore, but things like use transition, use deferred value, et cetera, et cetera. I was asking, , would these things actually help? Because this is exactly our use case. Like some of the renders are expensive. And he said for our cases. No, not really. So I gave up on that idea, but I, now that you mentioned it again, it might be something, worth trying. Yeah, because you literally kick off a render somewhere off screen and show a loading indicator until that's done, and when it's done, it's committed. I know the code base for Replay the dev tools, uses useTransition heavily and it does feel way more responsive than, Something as heavy as DevTools to have to try would yeah. And then [00:12:00] also use deferred value similar it just state when it has a few cycles. Awesome. You mentioned so many interesting things in your talk. I love your call out to Triangle Company. There was just so many funny pieces there. But I'd like to still maintain. Our focus on hooks because you were really critical about hooks in your presentation. What are some of the weird or confusing rules of hooks that you mentioned? And I'd love to maybe get the less condensed. I have 20 minutes for my talk presentation here, but talk about that in a bit more detail. hOoks I feel like we're a. somewhat natural or not natural, but more like a required evolution of function components where I remember just refactoring as many of my class components as I could to function components. But then once I needed state and stuff, I'm like, Oh, I guess I'm back to classes. So hooks were a very much needed thing. But at the same time, when they were introduced, they were still a little weird. It's like reacts gave us. a solution. And the fact that they gave us a solution was really good. But the fact that it was this solution, it was like, it's a little [00:13:00] awkward, but it's still so much better than class components. We just went with it and the way that hooks work. If you're not aware, I know that you're aware you're a thousand percent aware, but people listening, if you're not aware is like order matters. It's React is basically calling your components line by line. And you could think of every time they call a hook, it's like, uh, you're pushing to an array. Hey, this is the state of this hook. And so that's why you can't do conditional hooks or anything like that. Because if the, if it goes out of order, it's Hey, I don't know which hook I'm referring to in this call stack. So that is why React has the rule of hooks where it's you can't call them conditionally. And. , there are some other things I completely forget. But that's one of the main things. And I noted in my presentation that . React should not pose this as these are performance, or these are coding best practices. Don't call your hooks conditionally. It's more this is a constraint of the way that we built hooks. You can't call them conditionally. Now, if each hook required you to have a unique [00:14:00] ID for each one that you specify, they could be called wherever the heck you want, as long as it's, Oh, yeah, so you can't call them asynchronously either. That's another one. But What this ends up doing really is coloring your, I don't know if you want to call them functions or components or things like that, where hooks can call other hooks, which can call other hooks, but it still needs to, you can't do it asynchronously or conditionally, et cetera. So that is really nice, but it's not really useful outside of react. And so that's why one of my biggest criticisms of hooks is that hooks are very much a react thing, and you can't. Easily combine it with react doesn't really work naturally with just. Like an API that works outside of React. That sounds like a tautology sort of brain farting here, but yeah, hooks are peculiar. They're awkward. especially because I think you pointed out use context can be called conditionally. it can, and that's because just like I said, React is trying to figure out, okay, which place in this stack does this hook state belong to? But with context [00:15:00] lives somewhere else. It already has a set place where that state lives. So it doesn't really need to refer to anywhere in the stack. So you could do that. That's probably better for a teaching perspective from the React team to just be like, yeah no, nothing conditional, even though yes, you can but maybe you shouldn't. And I also experienced this with server components. I've spent the past couple of weeks deep in server components, server component world, and partially for the book I'm writing, but also I'm just interested in the stuff and . It's a different world, David. Server components. For example, you can technically run hooks in server components, but the build tooling of various frameworks just prevent, if they recognize a server component, they will just fail the build. If it has use anything in it, it's not even a hook. If you have a function starting with the word use and you call it in a server component, it will just fail to build. Even though that's technically possible. And I'm sure they're trying to prevent a number of things like calling things out of order and so on, but it's just one of those things where you go like, why you mentioned server components in your talk at reactor alley but then you [00:16:00] conveniently ran out of time. I'd love to get your take on that and ideally, I'm sure it would be a service to me and all the listeners if that take is as hot as possible. Ooh. Yeah. I don't know about hot. I have a lukewarm take and that's like with server components and all of that. We're honestly my, my life right now is my startup stately. ai. And right now we're not using server components or anything like that. We're trying to stay off the cutting edge, bleeding edge, dull edge, whatever you want to consider it right now. And, yeah, server component seems like it would be really useful for simplifying the back end for front end. However, with the examples I've seen, I know that popular example where it's like, Oh, hey, you could, just call a, an SQL query right in your components. It's like you can, but you shouldn't. I understand why they're showing that just to show you how. The lines are blurred. It's a lot simpler to do things like that. But at the end of the day, you still have to follow programming best practices. That's [00:17:00] why I think simple examples like that are terrible as like a, hey, here's how you should do things. But they're really good in a, here's how things conceptually work. And I really wish they made that difference a bit more clear. so I'm curious because like I've seen a lot of people complain about that specific example for those who haven't seen it, it's this code snippet from let's just be honest about it from Vercel who's showing A server action that happens inside the body of a react component where you insert, you do something with a database calling a SQL tag template, literal function, and just passing in a SQL string with interpolation to it. I've seen a lot of criticisms around this because they go like, how can you just include a SQL string in a query, but it's not right. It's a tag literal. And the assumption there is it's probably going to do some sanitization, some validation. Et cetera. But again, that may not be the case. It may not be doing that. We just have no idea of knowing. However, Vercel's Postgres package exposes that SQL string and it's open source and you can go see what [00:18:00] it does exactly, which is safe things. So is the reason it gets all this pushback because it's teaching a pattern that could be abused easily? Is that why there's pushback? I'm curious what your take is. from my perspective and from, someone who's been working in open source for a while, There's always this dilemma of show the simplest example, but, just for them to understand, but hopefully not for developers to be like, oh, that's the way I should be doing things. And I experienced this in xData a lot where it's oh, here's a simple example. And then people are like, oh, wow, that's so complicated. I'm like, Yeah, that's because X8's meant for more complicated things, but I'm not going to show you the more complicated thing. And so that's why I think that Vercel and the React team are really trying to do here is show, Hey, here's a simple example of how you could interact with your server directly in your component, and I think as developers tend to do, they just zoom into that specific example and be like, Oh, that is, just asking for a SQL [00:19:00] injection and things like that. And it's I want developers to just imagine that SQL statement was instead a big insert server call here. And in, instead of like just diving into that specific example and criticizing it I think it was a fine example because it shows I could call my server from right here. But obviously you probably will not make a direct SQL call there. Hopefully. Yeah. Yeah. And it's in many ways, it feels a bit like seeing a tree in a forest and like hyper focusing on the tree when it's, there's a beautiful forest. Yeah. so I'm curious, what is the overlap? You mentioned stately a couple of times. I know stately because of our friendship and I've seen the editor and it's a pretty complex piece of UI. I don't know how much of that is. Canvas based versus not, and what inspirations you take from things like TLDraw and Excalibur. It's probably a discussion for another podcast episode, but what is the overlap? I'm assuming a lot of the things from this talk came from experience either from you or from other front end engineers at Stately. Is there overlap? What does that look like? [00:20:00] Oh yeah. This is definitely the most complicated react app that I've ever worked on. And I feel like there's, The best people to listen to when they talk about react are the people who are really deep in the trenches, people who have experienced just, through pain and everything tears, whether it's tears of joy or tears of sorrow of working with react and all of its nuances and just understanding from their perspective and from building complex applications just. What the weird parts are. And so with stately, we have definitely experienced just so many things because like you said, it is a complex canvas application and by canvas, we're actually using HTML and SVG. But there's a lot of moving parts, a lot of things that we have to subscribe to a lot of things where it basically goes into advanced reacts territory. Like we're listening for, pointer events and just handling. Things that are beyond reacts control. We have custom data structures that we have to listen to and [00:21:00] making that work within reacts neatly is really non trivial. So trust me, like I, I think one of the latest things to happen on Twitter was people talking about use memo a lot and it's Oh yeah, you shouldn't just throw use memo everywhere in our case. It could be a special case. We have to use memo. It's like our app just completely grinds to a halt if we don't use memo in the correct places. For those listening let's, I'd love to dive into that. What are the correct places? Cause I do see code bases where people are using use memo for literally everything, including scalar values. Like they'll use memo on zero or some value that isn't compared by reference. I'm curious if we could speak a little bit to that. Are y'all having to do that at Stately as well, or yeah, Yeah. And honestly, engineers, we love to complicate things way, way too much. And I think that the rule for like when you should use memo, it. It isn't even worthy of a blog post. It is step one, realize that part of your app is slow. Step two, add use memo to the parts [00:22:00] where you either measure is expensive or you have a good feeling that this is expensive. Step three, observe. Is it faster? Yes, keep memo. No, get rid of it. You don't need it. That's it. interesting? So it's a lot of playing by ear. Yeah. Just because to you, I do not trust the React DevTools. At least the, the official ones out. I know the Replay team are actually working on really good React DevTools. But with the current ones, it will say, Hey, this re rendered because hook 67 changed. And I'm like, I am not counting. tHat's so interesting. I've never heard this before. What I have heard is, You know, you memoize things that are compared by reference, what that means for those listening if you're not a JavaScript aficionado is objects, arrays, things like that, they're compared by their location in your computer's memory, they're not compared by their actual value, like strings, numbers, booleans, etc. And up until this discussion, honestly, I never saw a need to memoize primitive or scalar values that are compared by value. [00:23:00] But what I'm hearing is there may be value there in some cases, and I'm interested in these cases. I'll give you an example. And we recently refactored this again, but when drawing edges, like edges are the lines between nodes in the canvas they have to bend and they have to avoid certain things. So they're doing a lot of calculations just to find the best path. It's not just a simple line that we're drawing. And so obviously when you move things around the canvas and. This is something where use transition might be able to help a lot too, by the way. But every time you move something or change something that has to get recalculated. So we realized that's actually a big performance bottleneck because these are non trivial. It's basically doing a star search, complex algorithm, and it has to do it every single render. That gets really expensive. So we're like, okay, we need to optimize this somehow. And so use memo allows us to say, don't recalculate this value unless something significant has changed. For example, one of the nodes it's attached to has moved. Then you need to recalculate the [00:24:00] path because before we were just recalculating every single path, every single time. That's one of those places where we're like, all right, let's try it out. We tried it out and it made a huge difference. So we're like, okay, use memo is applicable in this use case. this may be getting a little bit too much into the weeds, but now I'm curious. Are you running that algorithm, this, star algorithm, I believe you called it. Are you running that while the user is interacting with the UI? That is while the user is dragging an edge, can a user drag an edge or is, are the edges automatically placed between nodes? So the edges are automatically placed. You could drag the label, which will change the edge and you could drag each one of the nodes, which of course will also change the edge. But every single time you move it, it does need to recalculate it. Otherwise it's just a weird user experience where the line isn't attached until you drop it. That's a little weird. So Are the so I understand that if you're moving a node, the edges are changing in real time and that, oh my gosh, that's a series of high priority updates for react. And that just sounds really complicated because [00:25:00] react will prioritize user interactions over. Non user interact. So if, for example, if you have a chat app and a message pops in, this isn't, you didn't do anything to prompt that. So React will deprioritize that compared to you typing on a keyboard. But in this case, you need to do a complex task while the user is interacting with the app, which means yeah, good luck. I can't, is this open source? It is not. So I've been considering making it open source. I think it'd be really cool. Yeah, there's at least four more conference talks you could do based on all these things. Yeah. Yeah. Have you felt the pain yet of React's coarse reactivity There are a lot of gotchas where it's basically it comes down to why is this component re rendering again? And even with class components, I remember we had this whole, why did you re render a library that told you, Hey, this re rendered, multiple times. And then that's where it went away once. Everyone realized that things were rendering twice just because React felt re rendering your component twice in strict mode. But yeah I definitely feel the pain. There's a lot of things that we [00:26:00] have to listen to and it's very easy to accidentally just be listening for something that the component shouldn't really care about. Like something changes and then it's like, all right, I guess I should re render, but it's no, you shouldn't. And that's where I do see the benefits of having something like a signal based system or FUSE reactivity system for that. That's so fascinating. I'm particularly tickled by this because yesterday at exactly this time or close to this time I interviewed Attila Fasina for the PodRocket podcast, that episode will be dropping soonish. And it was all about solid and all about the fine grained reactivity system from solid and how he feels it's superior to react not because of performance exclusively, but because it. fits his mental model of what should update and when and what I'm hearing from you as well. Yes you feel similar. It's probably going to be a massive migration, but the quick library has interop with react components and code bases. Do you think that may become some type of consideration for your editor? If things [00:27:00] continue to be slow and difficult? I think, and this is another mild criticism of React based on everything we did, all of our optimizations, it's baked into react. And that's something that I'm very allergic to. I really like having logic that doesn't care where you're rendering. And to be fair, a lot of logic is like that. And we have done massive refactors so that one day, if we say, Hey, we want this to be standalone JavaScript or in a different framework, we could do that maybe not easily, but a lot easier than, we could have before. But yeah if other frameworks enable this kind of. Performance I will say on the record that I don't think that react is well suited for for complex applications like this. I think it's just what we knew but like for things like canvas based apps, where you have so many things rendering and you have to have control and listen to things outside of react you're fighting against react at many points. And that's definitely the case with us. We found a new favorite react function, or at least I did of course, Mateusz knew about it for a while, [00:28:00] FlushSync. It's great. Okay, I want that, That also lets us escape outside or not escape react, but just we could say, Hey, just re render this now. Don't wait for the next, render cycle or whatever, just. Do this now, so it's a, it's a prompt to the scheduler no this isn't deferred. Do it now. It simulates probably user input, which is the highest priority. Exactly. Yeah. you know, we've been doing that and just all sorts of little hacks to say, Hey, React, we know what we're doing because we're in control of this external source that we have to subscribe to, and we know when things need to change. So more and more of our logic has been, just moving outside of React and hoping that Reacts does the right thing and re renders at the right time, et cetera. But yeah I think for the vast majority of applications, React is great, but for our Canvas application I don't, I honestly don't know what's better. maybe something like Solid or something. exactly. Something with fine grained reactivity, probably. Interesting. There's, I feel like this gives you at [00:29:00] Stately a unique and special position to be like some type of test bed for the new forget tool chain. Because use memo, use callback, they're going away. They're being deprecated in favor of this thing, which will just automatically memoize what should be memorized and really give you like fine grained reactivity, which is. what you're after. Yeah, I feel like there maybe needs some introductions to be made if they don't already exist between people to get you access to that. Cause what we're hearing is, it's currently in use in, on I believe WhatsApp and Instagram and it's exceeding everyone's expectations for performance. Yeah. Honestly, that's the number one thing I'm excited about with React. Just the forgets, optimized compiler, because you already have to do that compilation step with React anyway. So if React could just go above and beyond and get rid of the things that that components don't need and basically act as that reactivity system without having to have that runtime reactivity system for fine grained updates, then. That's magical. Yeah, exactly. In fact so I got a hands on tour of this from Satya, who works on [00:30:00] this full time and it's very magical in that it exactly, as you said it, it removes the runtime reactivity cost by deferring it to the build time. However. I've also been talking to critics of this that, they make the very accurate point that you still need to walk a tree of DOM, of virtual DOM nodes to compare regardless of whether it's memoized or not. So that walking of the tree still has a cost versus in a fine grained system like solid or something similar. You just never have to, like updates are disconnected from DOM. From VDOM and from Realdom, they're not in the same world. And because of that, there is no walking of trees. And therefore the argument, this is from Mishko Hevery from QUIC, is that signals are always faster than React. Always, because you just never have to think about a tree of nodes. But we're digressing a little bit. Let's come back to your talk and talk about You mentioned you should not have to lift state up as we were taught with React but instead lift state out. [00:31:00] As a person who just shows up every single time the word state is mentioned on social media, a dude with a state machine company, what does that mean? You shouldn't have to lift state up, but lift state out. Like, why? so it's because react for the longest time has had this idea that your components tree is the same as your data flow tree, which is. Definitely just completely false. Things can flow, just many different ways. And the way that your components are structured should not be the same way that your data flow is structured. And that's why frameworks like really exist. And that's why react query is doing a really great thing with caching. Actually, yeah, just to give you a really simple example. And by you, the listeners let's say that you have to fetch the same data the. The stock of an item in a shopping cart in multiple places, both where the item is and also maybe you have a shopping cart thing on the side and you want to see the like how many is in stock over there too. So that, that might be a fetch call. But typically in reacts, the idiomatic way [00:32:00] is okay, it's needed in this component. So you're going to fetch in this component. And so what ends up happening? You end up making two fetch calls because it's like at completely different parts of the tree and to react solution is, Oh yeah, lift state up. So basically find that common ancestor of the two, which might be some. Completely arbitrary component, by the way. And worst case scenario, it's the actual roots of your entire app. And it's just do things there where it's completely unrelated to the components in question. And like I was saying, that's why react query is good because it's like, Hey, we realized this is the reality people are going to fetch in components. So at least we'll do some caching so that they're not. Duplicating requests and things like that. And so my thinking is, and my position with state machines and all of that, and especially with my library X state is that the reality is that your data requirements, like this core brain of. Here's the data that your app needs. Here's how it's going to update. Here's all the services involved [00:33:00] is actually pretty decoupled from your components tree. A lot of the time not all of the time. I know there's some cred apps where it's no, this component definitely matches my data structure. But so by lifting state out, you're relying more on a subscription mechanism. And that's why I think the usink external store hook is so great because it allows you to do just that. Listen for some external source where it's like, Hey, I'm in charge of the data and I'm in charge of the logic that has nothing to do with the UI, but the UI can consume that and transform it and then display it as it's needed. And. I like that, and a lot of people who have been using XState, or at least using libraries that are similar to XState also appreciate that because it makes it really simple to take that, test it in isolation, maybe use it in different components, refactor the way their UI is, or even take that and put it in a different framework if they need to do that. And I really love that flexibility, so that's why I'm... And can't lift your state out. I [00:34:00] don't even know if that's a thing, but it's a step beyond lift your state up. I so much value there because like you said, you can also then port your state to another framework and I think the real unsung hero here, and I say unsung because we haven't talked about it, is the testability of it all. You can literally test your entire machine, all the dispatches in isolation and Reliably know that your app's going to follow. Do you think we've, do you think used, this is a really pointed question, but I feel like I should ask it cause I have opinions about it. Do you feel like use state just shouldn't exist? think it has its place. It like it should really be used data, where it's like, Hey, I, me, the components, I'm in complete control of this data. Like when the user types in here, this is exactly the data it could change at any time. And there's no rules about it, but I really wish that. First of all, I do think it just. I just really think that, or I really wish that developers realize that specific hook is really meant for unbounded [00:35:00] data. So data that you completely accept, it could change at any time. There's no rules about it. As soon as you have any rules about that data, and by rules, Oh, this is a number that can't be more than 10. Like just tiny rules like that, or this depends on another value, then maybe it should be something different, but Interesting. It sounds like we're setting the stage for content. around the various kinds of state, right? Because this advice to lift state up may have been an oversimplification looking back and hindsight is always 2020. So it's not critical of anyone's work, but if we look back 10 years to when react was introduced, lift state up, didn't really specify, okay, but what state and whose state, because I fully agree with you, I think using you states great for an isolated. There's a new state, but there's a new hook, by the way, that is coming to react soon. And fun fact is re is exported from react dom, not react, which I think is cool, but react dom is exporting use form status and use form state. And both of these, confusing. [00:36:00] Yeah. Is where you basically link an action and. Certain return values that the server action it's used from state should really be user action and use form status is okay. Is my form pending submission? Is it. Does it have a response? Is it errored? Etc. So really useFormStatus is supposed to be useFormState and useFormState is supposed to be useServerAction. That's my hot take whatever. But the point I'm trying to make is I think useState applies for or should apply to State that is just very local. And the moment state starts to make it up or starts to make it out into other components, there's probably room there to reconsider, Oh, maybe this should be part of my like X state store or my Redux toolkit store or something like that. And that education, David, hasn't happened. And maybe I'm thinking it should starting with this podcast episode. Yeah. And it's something that I think I mentioned near the end of my talk with. You sync external store, just because there is that missing part where it's let something else [00:37:00] completely outside of reacts, manage your store. And if you look in the newest reacts docs, you sync external store actually provides an example. And it's a, to do a little to do app example, where you could add it to do complete to do remove it to do. And they make that toy example. I'm like. That's it, or that's almost it. React literally just gave an example of here is how to, have states that's global or global ish and not tied to your components. And you wonder why things like Redux Toolkit, Sustained, and maybe one day XState are so popular. And it's because it is a common need in applications where it's listen, I am tired of having to juggle around my states and play Jenga. And so you're basically playing Jenga with your states. You're like, let's move this up to the top because, whatever. And it's just annoying to do that when it's like, Hey, let me just have this live in module scope and then read it from wherever so much easier. Yeah. And what they don't tell you is you probably introduce. Prop drilling or unnecessary re renders, right? When you lift the state up like that and you sync [00:38:00] external store, it really is the solution to all of that. It's the solution to prop drilling because it's an external store and you get a snapshot which is I think the second argument to the hook. Which, yeah that's the answer. So I think a big takeaway for a lot of people listening is rethink your state. And perhaps, I don't know if you'd agree, and perhaps stop playing Jenga and consider useSyncExternalStore. Is that track? Yeah. Yeah. That tracks. And if you have component state, use reducer is pretty great. I wonder what the connection between useReducer and useSyncExternalStore is. Cause if you useSyncExternalStore, you probably have a large store where components can subscribe to a subset, like this getSnapshot function. The second argument to useSyncExternalStore is basically a selector, right? Or it could be. So then do you even need useReducer if you're using syncExternalStore in that case? Is, are they not similar enough to where you could just use one over the other? So it, it depends. I would consider like the use case for using external store [00:39:00] is. The fact that it's not tied to any specific components, but if you do have component states, then yeah, I would just use reducer just because you already have that built in subscription mechanism, but that's also interesting too, because you don't have a concept of a selector with use reducer. Once you use reducer, it's every single state change, you are guaranteed a re render. And same thing with use states. Can we clarify for people listening what a selector is and why it's useful? I think there may be people listening going what are you guys talking about? Oh yeah, sorry. So a selector, it's a function where it selects a value. So let's say that you have a bunch of to dos in a to do store, you could use a selector and say, Hey, I actually am just, I just want this one to do, so you could be like, Snapshot. todos and then whatever the idea of the to do is, or you could filter them or you could just transform that data in any way you want. Can I ask a silly question on behalf of the listeners? I've seen some very large Redux State Trees stores where it's a big object and [00:40:00] each key represents a route. And each value of that key represents like the state for that route, for that user. So in this case, would a selector then be like, okay, listen I don't want this other routes state, I want my routes state. And not only that, I want my route state for this specific user, so a selector. It enables us to take a very large store maybe and just get a subset. of The keys or rather subscribe to a subset of that large store object such that only when that subset changes are component re renders. Is that close? yeah, no, that's exactly it. And that's one of the main use cases for selectors. You don't want your component to re render when anything else in the store changes. That was a big problem with Redux in the early days. So I'm glad they're really pushing selectors now. How is XState solving that problem? So we have a use selector hook itself. And so that just takes, and it's actually really flexible. I really want to make it so that it's not tied to X state. And that's one of our big goals, but you selector takes something that you could subscribe to and [00:41:00] a selector function, and that's pretty much it. And by something you could subscribe to, I mean something with a subscribe function. So you could even pass a SvelteStore, whatever it would... You wouldn't use a SvelteStore in React, but you get what I Is it type safe such that I get the schema of the object in my second selector argument when I pass in the first? It is. And you have a third argument for the comparator. Where you could say, hey, I just want to like shallow compare this, or I want to add a custom comparator, or, things like that. That's incredible. , I didn't know that useReducer doesn't have Selector functionality that you can maybe import from react. I'm curious. I wonder if react should maybe just export you selector also, or if use reducer X, I don't know, whatever. But that needs to be fixed. I feel like um, We've got a few minutes left. I want to hear about stately. I want to hear about what's on the roadmap. I want to hear about how react is either making that easier or harder. And I want to tie it all together to your talk and how it fits in. Can you do that? Yeah. Real quick, stately as quartz it's a [00:42:00] state modeling platform, we make it really easy to model state machines and state charts and basically workflows in general. And you could take those visual models and you could export them as code or now as markdown tests, et cetera. We're announcing a few things next week where you could explore a lot more things too. So that's pretty exciting. That's very ominous. What do you mean? Export like react components or Redux toolkit. Stores or, Don't spoil it. Anyway, uh, I will neither confirm nor deny that. But yeah and at Stately, of course, we use React a lot. It's built on the open source project XState. And XState has been in version 4 for a while. So if you don't know, XState is a library for making state machines, state charts, and working with the actor model in JavaScript and TypeScript. And we're working on releasing X state version five, which is much more focused on the actor model, which is Really good for people who might be thinking, I don't really need a state machine, or I don't need to rearrange my state so that it's a state machine [00:43:00] or a state machine is too complicated. Now you could use other types of logic too, as the actor logic. And then you could do just like I said, with you selector. Just take the actor, select any value from it, and it will automatically subscribe to those values. So the way React fits in is that when you have simple states, It's easy enough to use state, use reducer, even use libraries like Zustand or Redux, but I feel like for apps where you have a lot more complexity, and I'm saying things like multi step forms or complex UIs or even canvas based apps like ours, there's a lot more states that you have to think about and a lot more complexity in your logic, and if you use simple tools, then it's going to just Ironically, blowing complexity, like it's going to just become unmanageable. And so with the idea of state machines and state charts, you could really constrain that logic to certain states and events. And those are the only two things you really have to think about is, I send something in events and I expect it [00:44:00] to be in some states and maybe execute some side effects. So X state has that notion of executing side effects too. So yeah, we're releasing X8v5 soon and updating a lot of React examples. Yeah, because React is definitely our heaviest usage of that, but we do want to make it usable for the backend as well. And this sort of ties into my previous points about the idea of lifting your state out so that it could be used in multiple locations, tested, etc. It's not UI, and that's something we're doubling down on. that's amazing because it's not tied to your UI. Do I understand correctly that you could even just use a, an actor, I guess in X state five in like server components and share state between RSCs and client components that way, or. It is possible. It's something that I have to experiment with, but I think it would be a really cool example because, people who work on, for example, next JS apps or remix apps typically they're full stack developers because they have to deal with graph QL, the database, et cetera. And as part of the backend, you have to work with [00:45:00] workflows too. You have to say Hey, when the user uploads this file, I have to do these three steps and then notify the user, Hey, it's done. Or maybe I have to send the user intermediate uh, notifications where it's like, Hey, I finished this part of the thing. Now I'm doing this. Now I'm reticulating splines or whatever. And then finally it just comes out the end and you have your thing and you want the user to know every single step of that workflow. And so state machines are a great way to represent that workflow and it's not something that has to live on the front end. So. You're making me really want to just make an example with server actions or something where you can basically call a state machine in the backend, in your Next or Remix app and have it do whatever workflow you want, Interesting. Well, I'm very, very eager to try that out. Listen, David, it's been such a pleasure. I, any opportunity to talk to you is a great one. And I'm going to miss you at React Day Berlin. Unfortunately, you're not going to be there in person. But I guess this should make up for it. Thank you so much. You've shared so much information and we have poked fun at React, but we also. Appreciate it. A lot of the heavy lifting that it does. We've talked about our [00:46:00] hooks. We've talked about X state. I'm personally excited for X state five and the actor model. For me and everyone at the podcast, thank you so much for coming and sharing all this knowledge for me and the listeners. I, we really appreciate it. Thanks so much for having me.