Transcript
00:00 Hey everybody, this is Kent C. Dodds and I'm joined by my friend Ricky. How are you doing Ricky? I'm doing really well. How are you doing Kent? I'm super. Always happy to chat with you. And yeah, Ricky, let's see, you and I go back.
00:16 I don't know, it's got to be, like, it's definitely pre-COVID. When did we first meet? Was it at a, it must have been at a React conference or something. Yeah, were you at React Conf 2018, the one with hooks?
00:30 Yes, I was there. That must have been it. So yeah, we've known each other for quite a while. It's actually amazing to think of, you know, that was 2 BC. That's before COVID.
00:45 But yeah, it's been a while and it's awesome to chat with you about React and everything here. Can you give us a quick intro to yourself so folks get to know you a bit? Yeah, so I'm Ricky. I work at Meta since 2018 when we met at React Conf.
01:01 I actually already accepted my offer, but hadn't started yet. I worked on, when I joined Meta in 2018, I worked on React Native for a year and a half until COVID hit. And then I moved to the React team. I've been working on the React core team ever since.
01:18 Very cool. Yeah, I think that I had been following you on Twitter before that, because I remember meeting you there and recognizing you from Twitter. You know, there's sometimes people you just see on Twitter a lot, even if you don't interact a ton.
01:36 You're in the same circles and talking with the same people. And so it's always cool to meet those people in real life for the first time. Yeah, that's actually one of my favorite things about being on Twitter, is just all the friends and connections that you make.
01:52 And then it's really cool to be able to meet them in real life for the first time, mostly at conferences. It's really, really cool. I usually get the, like, you don't look like your profile picture. A lot of people don't. I especially don't. But yeah, it's fun.
02:10 Yeah, this is why at Epic Web Conf and Remix Conf, we always print people's Twitter avatar on their badge. So that, like, oh, I know who you are. Yeah, I have my Remix Conf badge here. Yeah, let's go. Awesome.
02:26 Yeah, I've got mine back there somewhere. It's in there. Well, cool, dude. So actually, that makes me think, like, eventually when we are multi-planetary or, like, people are on Mars, you'll, like, interact with people, maybe on X or whatever else.
02:42 I guess X will maybe be the only social media platform allowed on Mars. Who knows? But, like, you'll just be like, well, I guess we'll never meet. We think now about, like, folks on the other side of the world and, like,
02:59 it's very possible we won't ever meet because it's just so far to travel. And, you know, multiply that by a billion. It brings a new meaning to remote. Yeah. And, like, what are time zones at that point? Like, I don't even know. Like, that's going to make a mess.
03:17 But, yeah, so you're on the React team. Was that the original goal when you first interviewed to work at Meta? Was that what you were hoping to be able to do? Yeah, it's funny. I actually interviewed at Meta in 2016, and that was my goal. And when I asked the recruiter, I was like, you know, what do you got to do to get on the React team?
03:35 And they're like, yeah, well, they have boot camp at Meta. So they're like, you have to go to boot camp, and then you, like, pick a team. If they have headcount, you can join. So, but I really wanted to join the team because I've been using React since, like, months after it was open sourced. Oh, really?
03:54 Yeah, I was always a really big fan and, you know, kind of wanted to work on the team. So I kind of gave up that dream, and while I was working at a startup, I started doing open source, and I worked on Jest, if you remember. Like, when we met, I was working on the Jest core team,
04:13 and Christoph referred me to Facebook, and I moved from New York to London to join Facebook to work on the Jest team, although there were no promises. And the day I got there, they were like, oh, well, there's not really a Jest team anymore,
04:30 so pick a team. I was very fortunate that there was opening on the React Native team, so I joined React Native. Yeah, cool, cool. I interviewed at Facebook in 2015, like, the fall of 2015, and that was, like, my thought, too.
04:49 Like, I want to get on that React team. And the recruiters are like, yeah, so does everybody. Yeah, exactly. But, yeah, I ended up not accepting the offer to go work at Facebook, but you did, and you've had a really awesome time there.
05:07 You've been there for now, like, six years. That's quite a while. Yeah, it'll be six years in November. I just finished my recharge. Every five years you get one month of recharge. What does that mean? Like, you just chill and hang out with your family and that sort of thing? Yeah, it's like one month of paid PTO.
05:26 So you get to kind of do whatever you want, travel, take some time off, recharge. Yeah, that's cool. That's kind of fun. So you're just getting off of that. Then what are you working on day to day?
05:40 Yeah, so day to day right now, all kinds of stuff. One of the main things that are top of mind right now are finishing the docs for React 19 and documenting things like actions. That's a really high priority.
05:59 The use API. We have docs for them now, but they're not complete, and they don't really give you, like, the full picture of what you can do. So as part of the 19 release, I want to make sure that we get that in.
06:13 I also do a bunch of work supporting, like, internal teams at Meta that are using React, helping to understand things that are in the docs. And one big thing that I'm doing right now is we have great docs that Dan wrote on not using it.
06:31 Like, you probably shouldn't use an effect and really helping teams to, like, understand that and also looking into their use cases to understand, like, what is difficult about, like, implementing those recommendations in the docs and are there things that we can make easier, stuff like that.
06:50 And I also kind of do side projects, build apps on the side to stay up to date, both working with product teams and building my own products and staying up to date on how you can use React. Yeah, okay, that makes tons of sense.
07:04 So I actually saw your post just a couple days ago where you said that most things that you're doing in UseEffect should probably be in events. You want to, can you elaborate a little bit on that?
07:19 Yeah, so one pattern that I'm seeing pretty frequently is, like, you want to do some kind of side effect, right? Like, think of video player, for example, right? When you click play, you want the video to play. Pretty simple.
07:37 I think we even have, like, a doc that uses this as an example. And so what is sometimes the easiest way to do it is, okay, well, I have an isPlayingState already to show the playing state on the button, so I'll set the isPlayingState, and when the isPlayingState changes in an effect,
07:56 I'll fire, like, I'll call ref.current.play and play the button in the effect. This has some problems. One problem is that you're delaying when you actually play the video to potentially very far away from when the button was clicked.
08:15 So you can have this long delay waiting for rendering to finish to start the video and actually play the video, which can cause this delay. If there's any kind of, like, prefetching that you need to do to, like, load the video, you're not starting to load the video until you've already updated the UI.
08:33 So waiting until the UI is updated to, like, perform some side effects is very often, like, much later. You'll also see this with, like, data fetching, right? Not starting network requests until after the state, like, has rendered to the UI.
08:50 It's much better to, like, hoist those up into the event, like, the user event that triggers so that the network request starts faster. This kind of relates to the, like, the use hook and the relatively controversial
09:06 not creating a promise in render aspect of use. But if you think about it, if you are creating it in render, you're creating it too late. Like, there's some event that started before that where you could start initially, like, start the request.
09:22 And then by the time you need the data, that request could have finished by the time you get to, like, where the use hook is consuming the promise. So that pattern is usually... The one problem is that it's sometimes very difficult to do that. So that's something I'm trying to think about right now is, like,
09:40 how can you make it easier to do those things in effects? I think actions help with that. I think server components help with that. But, yeah, that's kind of, like, that's what I meant there. Yeah, yeah, that makes sense. Doing these, like, cascading renders where you are basically, like,
09:59 imperatively writing the code where it's, like, if this changes, then set this state. When that state changes, then do this. When that changes, then do this. When that changes, then do this. This is the whole thing that we got rid of with React. Yeah, yeah.
10:15 But we're wiring up all these, like, chains of effects and set states to get to, like, the final state that needs to happen. So you have these cascading, like, waterfalls of renders until you get to the final thing that you want the user to see. And it's much better to hoist that all up, do all the work in the event,
10:34 and then render the UI once. Yeah, you know, that actually makes me think of the whole render as you fetch paradigm. That was, like, back in 2020 or even before when y'all were starting to talk about that.
10:51 And I remember in Epic React version 1, I had an exercise where we demonstrate the problems with, you know, render then fetch, and especially when you bring in lazy loading of code. So, like, oh, they click the button, now let's go lazy load and render. Get that component, and then we render it.
11:08 And then, oh, that component needs some more data. Actually, maybe start that earlier. So, and then also, like, effects that trigger effects, or state updates that trigger effects that trigger state updates, like you were saying. Very, like, that sounds a lot to me like a jQuery spaghetti
11:25 that we, like you said, we got away from thanks to React. Yeah. Yeah, I was always kind of hesitant, because I've heard people express this recommendation for quite a while, but I was always hesitant because I was, like,
11:42 struggling to figure out how do you deal with, like, if the component is unmounted, and canceling whatever thing you did in the event, or if there's, like, a race condition, or, like, they click on the button a bunch of times. So, what do you recommend for those sorts of things?
12:01 Is that the sort of thing that you have, like, an external state management or store thing, and so you just trigger events at that thing, and then that can manage those race conditions and stuff? Yeah, so there's multiple problems that you flag there. I think each one has different solutions, one of which is, like, the ordering problem.
12:20 And this is the problem where you have a button, and you click a button multiple times. If each one fires off, like, a request, and the requests return out of order, like, the first one could overwrite the result of the second one,
12:37 when you really want the second one to be the result that the user sees. Maybe you're updating a quantity, and every time you click update quantity, you want it to be the latest one you updated it to, and you don't want it to go back to a previous quantity. You don't want it to go from, like, four to three. I think that one of the nice—
12:55 one of the, like, root cause of this problem is that the UI library is not the one in charge of coordinating those requests. So in Vanilla DOM, you see this problem, and there was, like, some threads going around on Twitter
13:14 talking about this as well, because there's, like, a GitHub issue where we talked about maybe eventually warning if you pass an async function to an event handler. And it's like, well, why would you do that? Well, in Vanilla DOM, you have this problem
13:31 because you can pass an async function to an event handler in the DOM, and then you have this ordering problem. And so in React 19, we have actions. And so conceptually, what actions do
13:48 is they allow you to tie your async events to the rendering of the UI. And so if you use useActionState, for example, useActionState is designed as a reducer because it does ordering. So if you were to click that button multiple times,
14:07 it orders those clicks, and first will, like, run the first click, and then when that returns, it'll run the second click, and when that returns, it'll run the third click. But let's say you don't want it to happen sequentially. You can, like, you have the option of just dropping down to a raw start transition action
14:25 and adding in your own. Maybe you do cancellation, right? Or maybe you do, you have some custom logic for how you handle that ordering. But then you use that action in the event handler, and that kind of tells React that, like, when this button is clicked, this is all the, like, async side effects
14:43 that I want to happen. And this is, like, the logic for how you do those. Yeah, I really am glad that you brought that up because the useActionState making the action be sequential was probably my biggest frustration, I think,
15:02 with that new API. And I recently was like, okay, how could I work around this? And I did what you suggested with the start transition. And you talking about it in this way kind of helps me appreciate why it is that way
15:18 to, like, ensure that sort of consistency by default. And then I can go and add some complexity in there if I want to optimize things. Like, literally the only use case I can think of where a user is clicking a button repeatedly is for the quantity in a cart. And that would be the one case where I'd be like,
15:37 ah, I just want to cancel the old one and let the new one go. Really, that's not... It's actually not a huge ask or a huge amount of work to kind of drop down and now manage that transition myself. So I'm glad that you brought that up. I feel actually a lot better
15:54 about the useActionState now that you say that. Yeah, and I think the... And this is one reason why I really need to, like, ship the docs is that we can help to explain those things. I think the theory for the useActionState hook is that it is... It's provided as, like...
16:12 Like, you can implement useActionState other than the permalink argument for progressive enhancement. You can implement useActionState in user land. It's provided as just, like, a convenience where for, like, many cases you could just drop it in and use it and it would work as expected.
16:31 Because if it didn't do the sequential ordering, then you would, like, almost... You would hit the... You would go right back into hitting the race condition case. If it did the cancellation automatically, then you would have the opposite problem where it's, like, why is useActionState always canceling,
16:49 like, my, like, requests? Like, I need those requests to go through. You can't automatically cancel them. So there's not very many, like, fits-all-use cases. Well, useActionState also doesn't actually know what your action does by design,
17:06 and so it couldn't cancel the request automatically either. So, yeah, there's a lot to this, apparently, that the React team is thinking about, which I appreciate. Yeah, there's one other piece to that as well, which is useActionState, if you pass it...
17:25 The other thing that does the sequential ordering that I think is potentially controversial is form actions. So useActionState has the ordering build-in. Form actions has the ordering build-in. Server actions doesn't. It's a little bit of a fud. I think that's a framework-specific choice
17:42 for server functions to be ordered. But form actions are ordered, and conceptually, the way to think about that is that in a, like, raw HTML form, when you submit a form, it takes you to either the next page or reloads the current page.
18:00 So it is always sequential in the HTML form. You can't submit forms multiple times. So it's the same kind of principle there where we're trying to get... Like, embracing the platform and helping use the platform primitives in the way that they're supposed to be
18:19 with a little bit better DevEx. Yeah, yeah. I think, though, with the platform, if you click the Submit button, it triggers the request. If you click another Submit button or something, it will cancel that request. But again, React doesn't know or care
18:37 what your action is actually doing. And so, yeah, it's very interesting. You know, the thing that I have really come to appreciate in building Epic React V2 has been the power of transitions. I think when I did Epic React V1,
18:54 I had a workshop that was React suspense. It was experimental. This was back in 2020, so it wasn't really officially launched yet. And back then, we definitely talked about transitions and things, but it was pretty unclear what that really meant.
19:12 And now, years later, it is so clear the value and benefit of React's focus on transitions. And so many features are falling out of this decision to have concurrent features and transitions.
19:28 What would you say are some of the most interesting things that have fallen out of the transitions feature in React? I would say the number one most interesting thing to me is useOptimistic. I think that useOptimistic almost gives you the ability
19:46 to make all state updates transitions by default, and if you want them to be synchronous, you could use useOptimistic. And there's this—I think if we could, if we were starting at the beginning, we may actually—we may—we would probably do that.
20:05 Because you really— there's very small use cases for wanting to do a synchronous update to state. A pending flag is one of them. And actually, startTransition uses useOptimistic under the hood to update the pending flag. That actually—yeah, that makes sense,
20:22 and that actually kind of helps contextualize that isPendingFlag, yeah. Yeah. I mean, it didn't used to. It used to just do a synchronous render, but that's kind of what useOptimistic does when you, like, add an optimistic state. But really, most of the state transitions in your app
20:41 should be transitions. So I think that's, like, a really powerful hook. It's almost like a useSyncUpdate opt-out of transition hook, which I think is fun. I think that other things that are super interesting to me about transitions and suspense
21:00 is the way transitions handle transitioning to new trees that suspend and refreshing data in place. Like, at the point now where when I'm, like, using a UI and I, like, click on something,
21:19 and it goes back to, like, hides all of my content and shows a spinner, it just drives me nuts. Yeah. Because it's like, why are you hiding this thing I'm already looking at? Like, just show me a spinner to tell me that, like, the thing I clicked on is doing something in the background
21:35 and then show me the next state when it's ready. Hiding lists of things that I'm looking at just because you're waiting for, like, a request to finish, it's just unnecessary. But Start Transition is smart enough to know whether it is, like, refreshing a current tree,
21:54 so it does it in the background, keeps the current content, or if you're transitioning to new trees, new components, then it can go and start showing a fallback for those new trees automatically. And you helped me on X when I was trying to figure that out
22:12 by just saying, oh, you use a key. Just throw a key on there. Like, if this is intended to be a new tree, throw a key on there. And that's the way keys have worked since the beginning. And so, like, it just really, it's interesting how these things fall out of these really great design decisions.
22:31 Like, it's been consistent over many years. That's one of the things I love about React is just how thoughtful everything is as far as the design of the framework is concerned. Yeah, it's been really interesting to me joining the team,
22:47 seeing, like, how that comes to be the case. I think it's just a very first principles approach to things. And then things just tend to, like, fall together and work together really well. It can be frustrating,
23:05 especially I was frustrated, like, on the outside. Like, oh, why can't they just, like, add an API to do this? Or why can't they just add an API to do that? And then, like, over time, you can see that, like, well, it's a good thing that we didn't, like, add this because if we would have done that, we couldn't do this.
23:22 And so there's, like, a really, like, innate desire to get to the global capabilities that we could get and not get trapped into a local maximum. Yeah, yeah, I like that.
23:40 All right, Ricky, I'm going to maybe put you on the spot here. One of the, relating to transitions, one of the hooks that I found is the most difficult to explain and understand is... Use deferred value. Use deferred value, yeah. Yeah, so that one.
23:59 I would love it if you could try your explanation for use deferred value. How do you explain that hook, what it does, and how it's useful? Yeah, use deferred value is defer updating this value until later. Okay.
24:18 My mental model for it is, and you can actually use it as a drop-in replacement for use debounce. Oh, okay. So imagine it was just called, like, use debounced value. So the value that I give it, I'll debounce a render for updating it until later.
24:36 So if it changes multiple times, since it's debounced, it'll be interrupted, and you only get, like, the final update of the final value. Like, the tricky part about it is the, just the API shape having, like, pass a value and it returns a new value, and then which one do you use,
24:55 but you get used to it pretty quickly. The advantage of use deferred value over use debounce, like a use debounced value hook, is use debounced value has just a, like, static amount of time that it will wait, where use deferred value will immediately start rendering
25:13 that next update if there's CPU available. So it kind of auto scales with the performance of the device. If you're on a fast device and there's no other, like, work going on, it'll immediately commit it. If you're on a slower device
25:30 or there's a lot of other, like, updates or events happening, then it'll defer it a little bit longer. So it kind of, like, auto scales with, it's like an auto scaling debounce. Which probably doesn't help if you're not familiar with, like, these terms. You're like, what are you talking about?
25:49 But I just think of it as, like, my mental model for it is literally, like, as if it's calling start transition, set state, next value. Yeah, so it is important to relate it to transitions
26:06 and, like, debounce this value until the transition is done and then you can be the value I gave you. Yeah, we use it in Epic React, I think, three times. Once is for performance optimization, which, like, honestly,
26:24 of all the performance exercises in that workshop, the use deferred value one is my favorite because you look at that flame graph and you see those chunks of work in just, like, little bits and you're just like, oh, my gosh, it is so cool. It is so cool. Are you doing, like, a filtered search
26:41 where every time you type a character, it searches? Yeah, yep, yep. That's exactly what it is and it's just beautiful. It really, like, you compare the before and after and it really is amazing. And it's, like you said,
26:58 it's based on the device. And so if the device is super fast, then, like, use deferred value doesn't need to chunk things up too much. But if it's really slow, then it chunks it up and it feels quite fast. So, yeah, then we also use it for, like,
27:17 we built this mini-router in the React Server Components workshop where we're building a framework out of React Server Components. And the router needs to know what the next location is during this transitional period. So we have the current location stored in state and then the next location comes out of,
27:35 or actually the next location is in state and the current location comes out of use deferred value. And it's so simple, really. Like, the biggest trick is, like, wait, what is this thing doing? And I think, I feel like I do a pretty good job explaining it.
27:53 I'd love feedback from people watching if they went through that and were confused. But I think of all hooks, that one is the most powerful and still a little bit difficult to understand. Like, the idea of,
28:10 oh, this is just a value that is deferred. Like, it's updated later. Like, okay, we can say that. But understanding how it actually accomplishes that I think gets a little bit tricky when we talk about, oh, well, it's going to render twice. Oh, well, what does that mean? Yeah.
28:28 Yeah, one other piece to it is that it's not just for, like, CPU performance. It's also network performance. Because if that value needs to suspend to wait for data, then it can do that immediately and wait for network.
28:43 And if by the time you, like, change the search input again, the network hasn't responded, then they can, like, cancel that and start another one, which works really well for using it with suspense.
29:02 Yeah, that's another use case that we have it for, is that we're doing a filtered list, but it's making network requests as we're filtering. So, yeah, what is kind of cool about this is that React doesn't really add,
29:18 what should I say, like, feature-based features. Like, it's not this thing is for this one particular use case, but rather, like, here are the building blocks that will enable you to build all kinds of different UIs. And so the fact that use deferred value
29:36 can be useful for performance as well as managing loading states for those type of interactions, I think is just evidence of that. It's pretty cool. Yeah, I think that's kind of the core philosophy, is to create the primitives
29:55 rather than all the use case-based things, because everybody's use case will be different. And I think that philosophy has been why React has been, has such a large, like, ecosystem. I mean, just think of the number of different form libraries. On the one hand, you could think that's, like, a negative.
30:13 Like, why don't you just have, like, the form, like, best form library built in? But on the other hand, if it was built in and it didn't do it the way that you needed to do it with your particular company's needs, then you'd be like, oh, this thing in React sucks because it doesn't work the way I need it to.
30:31 So by building the primitives and allowing library maintainers to publish libraries for specific use cases, then that allows you to have, like, a really big ecosystem that can grow and thrive where everybody has their, like, niche use case
30:49 and does that niche use case really, really well. Whereas if it was all built in, you, like, wouldn't have that opportunity to contribute in that way. Yeah, 100%. I felt this way for a long time,
31:03 that because React has fewer opinions and, like, doesn't make a bunch of decisions, that enables the community to innovate. Where, like, if React was like, well, this is how we do animations,
31:21 then anybody who wants to do an animation is just going to do the built-in way, and then, like, people won't innovate. They'll just say, well, I guess I'll just, like, make it work with the built-in way. I don't want to do something different from everybody else. And so I appreciate that aspect of React.
31:38 And I know, like, some people, like, especially in the early days, I don't know that this is as much anymore, but a lot of people would compare React to other frameworks that are more opinionated and have lots more built-in and say, like, it's really nice that I don't have to make these decisions and wire things together,
31:56 and I can appreciate that. But I think it's pretty clear that React is the winner here as far as, like, size of ecosystem. And I think that level of innovation is only possible when React leaves that space open for people to innovate. Yeah, I think it also relates to, like,
32:16 that's why we recommend using a framework now, is that, like, really to build an app, you do need some sort of opinions built in, and React doesn't have those opinions. And building them from scratch is really difficult, especially over the years. It's just become harder and harder
32:34 with all of the different ways to build an app to get the best performance with SSG and SSR and server components and having routing and bundling all working together. You really need both the option
32:52 to pick a framework that already has some of those opinions built in for you, but also have the option of multiple frameworks that each make different tradeoffs. I think that that's a really key piece of it as well, is that React could just... There is a world where we would have just, like,
33:12 made Create React App the framework to build React apps, but that wouldn't have been good for everyone. It would have been good for people that use Create React App, but if you have different needs, then suddenly you can't use React. It doesn't fit your needs.
33:30 There's different layers to it, like the core primitives with no opinions and then using frameworks that have some opinions, pulling in libraries that have their own opinions. Everybody can have opinions. It's opinions all the way down. Yeah. I like the animation case as well
33:48 because I think that that's a really good example of somewhere where we're lacking better core primitives, but it relates also to the earlier point that I was talking about with, like, we don't exactly know what that core primitive could look like in a way that works with all the different features
34:07 and server rendering and client rendering, and so we're opting to, like, punt on it until we have a better idea of that problem space because the worst case would be introducing the primitive. Everybody builds on it. It's used everywhere widely, and then we figure out, like,
34:24 all the problems with it, have to change it. Kind of like legacy context. We introduced this context thing. It didn't work right, so we had to introduce another one, and that one kind of didn't work right. Then we had hooks, and then you have all these, like, this baggage that you have to carry on. Yeah, yeah.
34:43 That's a great example, actually, and so I appreciate, like, there are some battle scars there that's driving the hesitancy, and, yeah, just let the community experiment with stuff, kind of figure things out, and that has always seemed to be
35:00 a really important part for the React team as well, is just we don't want to force the community to make changes all the time. Like, it's been years since we've had a major version bump of React. Like, years, and that's awesome. Like, that is so sick,
35:19 and especially, like, selfishly as an educator, that's really nice to not have to update my videos, like, on a regular basis because the framework keeps changing underneath me, so thanks for that also. But, yeah, I appreciate the focus on stability and migratability as well. Yeah, yeah, it's actually
35:38 probably the hardest problem right now because if you think about what you could do with React if you just did, like, a clean cut and didn't care about gradual migration, it would make our jobs way easier. I mean, if you think back to React 18 with concurrent mode,
35:58 that was one of the first big projects that I worked on. It would have been way easier if we just had the mode to opt you into all concurrency and you just had to rewrite all of your apps. But coming up with a strategy that allowed you to gradually migrate by opting into specific concurrent features
36:16 instead of getting it all or nothing took a lot of work and thinking and, like, trial and error. You know, I had to ship it in some apps and see, well, does this strategy actually work? Can I upgrade to React 18 with no code changes
36:35 and start adding concurrent features without breaking anything? Turns out that you could, and so we were able to do it. There's a ton of research that goes into it. Mm-hmm, yeah. Well, your massive amounts of extra work saves just gargantuan amounts of work
36:53 for everybody else in the ecosystem, so it is not unappreciated. It is definitely appreciated, and, yeah, thanks for all the work that you do. Was there anything that we didn't get a chat about that you were hoping we could talk about before we wrap up? No, I think you covered all, like, the main topics,
37:12 the events thing and actions, transitions. These are all top of mind, and hopefully pretty soon we'll be able to ship React 19. Super looking forward to that. Thank you so much, Ricky. What's the best place for people to keep up with what you're doing? Twitter. All right.
37:33 Yeah, whatever it's called in the future. Be social. I have DMs open, so folks that have questions and are struggling with anything in React, feel free to shoot me a DM. Super. Well, thanks, Ricky, for being so accessible, and, again, thanks for your friendship
37:53 and all the good things that you do in the world. We all really appreciate you. Appreciate it. Okay. Bye, everybody.