David Khourshid

useWat

Conference talk at React Alicante 2024. 33:06 long, 142 views on YouTube. Topics: react, react hooks, state management.

Watch on YouTube (React Alicante)

What is this talk about?

“When you're trying to figure out if you could use Reacts without a framework, because we did that with create React app and it was really simple.”

“React in general is functional programming, sort of, you know, with, React function components.”

From the opening of the talk.

Key takeaways

  1. You MPm install React, or you could use yarn at PNPM at React. 3:00
  2. React in general is functional programming, sort of, you know, with, React function components. 8:00
  3. In the React documentation, there is actually a really powerful hook that they don't really talk about too much, which is useSyncExternalStore, and this actually comes from the docs. 15:00
  4. Honestly, a lot of the weird things about React you're seeing today are just Next.js declaring things as stable, which React is declaring as not stable. 29:00
  5. Read the docs seriously, because once you actually read the React docs, which hopefully most of you do, you realize that the weird parts really aren't that weird. 32:00

Quoted from the transcript.

Full transcript

From YouTube auto-captions. Punctuation and capitals were restored automatically. Technical terms were normalized; some errors remain. 5,638 words.

0:00 Introduction

So sorry about that, just killed 30 seconds. Yeah, so my name is David Khourshid and I am going to be talking to you about use LS. If this works, we've come a really long way, you know, as a community. I don't know if you remember any of this stuff, but it was pretty much a nightmare to work with all of that. We had gulp grunts, JQuery, Bower, if you remember Bower and all of that. And so naturally, we have a replacement for this. It's called React, and, how many of you know, React here at React Alante pretty sure, most of you React is a really cool library. And it really eliminated the need for basically all of that tooling. Because all you need is React. And WebPack with about 15 web Pack plugins, you needed to manually configure. You know, most of the time, but now, of course, we have Frameworks for that.

Okay, so today I'm going to be talking to you about what and what is what? So I'm going to be talking to you about the weird and awesome things about React. Because React, honestly, is really awesome. It's an awesome. Some people call it a framework, some people call it a library. Like, honestly, who knows what the heck? React is? I'm going to explain that to you a little bit. React is a library, and it is a library for web and native user interfaces. But of course, you wouldn't be, you know? It's not surprising that a lot of people think of it as a framework, but officially, the docs say it's a library. Now. We do have Frameworks, though, such as Remix and Next.js, although for some reason, and you might have heard it in previous talks yesterday. They're known as Meta Frameworks, which it's like a framework of a framework, which begs the question, like, what, what is a framework?

So let me just clarify this next is a meta framework. And it's by Versel, so I guess that means that React is a Versel framework by Meta. Hopefully you could see the connection there, and if you don't know what Meta is. It's a company that made the you know, the famous birthday reminder app, and, you know this, it was actually really. Really cool because this app was their, highlighting. The highlighting feature of this app was that it used React. And it was really a Marvel of engineering. Except if you scroll too far, it crashed. So, um. React is a library that sort of acts like a framework, but you know, some people can think of it as a framework that thinks it's a library. It's really confusing. The point is that React is just JavaScript, you know, except for all the parts that aren't just JavaScript. We have J. S. X. You have to compile to Babel, Weback, hooks, server components, and really, most of React.

It doesn't really feel like you're in JavaScript. So I think a better way of expressing this is that Reacts mental model is just JavaScript. Except hooks are weird, though. We're going to talk about that a little bit. So how do you actually use React? Well, you MPm install React, or you could use yarn at PNPM at React. Or if you're a hipster, you could just use Bun and install React that way. And so once you get to that point, it should be that easy, right? Just install React in a few other libraries, too, and then are you able to create a React app? Yet? Not exactly so. If you go to the docs and you are trying to figure out how to start a new React project, really, it's telling you that there's a few options you could really use a framework. Like Remix or next, Remix is made by the men in Utah, and next is made by the Men in black.

So, and actually, you know what, I'm going to give you a better difference of Remix and Next.js, Next.js is all of these things, and remix is all of those things right there. So, when you're trying to figure out if you could use Reacts without a framework, because we did that with create React app and it was really simple. Which really, you know, makes you wonder why we have to use a framework in the first place. React does have a really long explanation of, like, well, actually, but really, yes, you can use React without a framework. And in fact, I would say that for some reason, the docs don't point. At this but it is really the simplest way to get started just create V and then use the React TypeScript template and you're good to go so now that we have React set up you know using V to your framework of choice how does it look it look looks actually those are the old docs I'm sorry about that in fact if you go to reactjs dogd dos it's going to tell you that these docs are no longer updated so you know it tells you to go to React. deev but these aren't the real docs either if you have any experience really that's that's where the docks are and that's where you'll get the most uptodate information in fact all you have to do is mention React on Twitter or anywhere else and one of the core maintainers will tell you that you're wrong so yeah so React has come a long way though you know originally we had classes in fact we had like dot PR components or something like that so we had even things before classes but it honestly looks the same and it is actually really impressive that React maintains such backwards compatibility that this still works today so you could still use React components and all of the old deprecated stuff or most of it in React too but you know we were going back to you know React being just JavaScript and it really is because those JSX calls are really just this you have React. create elements your tag name your properties and you know your children inside except that no one ever does this so really that whole just javascripts thing it's only if you're you know trying to be cool and show off your knowledge of React internals but really React it's it's really growing past this whole just JavaScript thing where you know eventually it wants to be its own language and if you don't believe me just look at reason which is now rescript or something like that yeah so JSX is awesome except you know there's some weird parts which is what we're talking about today who could tell me what's the problem with this zero exactly see you all know you're all Shell Shocked so now you have to add a check over here, you have to say is the item. length zero?

Or you have to, like, just coers it to a Boolean, which already looks weird. Especially if you add typescripts, then you have exclamation marks that mean different things, and then you know you have this. Items, items equals item, says item, which I'm sure some of you have written before, really looks like this tag over here. Okay, so pop. Quiz number two what is wrong with this component? No, no, no, you're missing a key, that's that's the wrong thing. So because if you try to do this and you try to, like, you know, forget the key, then React is going to yell at you, of course. And you know, we've all run into this. Thankfully, there are easy solutions to this. Just have a unique [Applause] key. Oh no, did someone screenshot that? I'm going to get in so much trouble? So, uh. React in general is functional programming, sort of, you know, with, React function components.

In that you should use functions. Unlearn half of JavaScript and then learn TypeScript, which really is becoming no longer optional. You know, I don't know who uses Flo, who works at Facebook over here, nobody. Yeah, so it's all TypeScript now, all right, so I only have a few minutes. So let's actually dive into hooks and some of the weird and awesome things about hooks. So first, we're going to talk about use Dat, and we probably already know that one of the weird things with used date is this whole thing over here. Where you expect it to get to a certain count, but, you know, after adding all these numbers, you actually come out with one. And that's because, you know, it's. It's not synchronous. So the count isn't changing between each of these calls, it's actually batching it up so that only the last one counts. And you sort of have to use this initializer function in order to get the counts that you expect.

Play from 0:00

9:00 What's not normal, at least to me…

And so this actually seems, you know, pretty normal. What's not normal, at least to me, is that you can't really use some normal JavaScript things like maps and sets in used date. And I know I've tried and I've really, actually wanted to use. Them, because they're very, very useful data structures. So there is a little bit of a hack though. And, you could sort of wrap it in an array and then unwrap it. And then when you're setting the sets, then you could add to the set and mutate that, and then you basically have a new array reference. And this works. But, you know, don't really do this. Yeah, yeah, React is just JavaScript, except for things that are part of normal JavaScript. Yeah, that's just something I'm upset about. But other than that, UST state is a pretty normal hook. You know, we have name, set name, and, you could update state, you could read state, except usually used state becomes use 8.

And it starts growing and growing. And then you have things like this. And these are actual real code, snapshot or screenshots that I got from Twitter. This is the most recent one. These are all used date calls, and it's pretty ridiculous. I don't know how you all live like this. Thankfully, we have a solution, but no one likes a solution. Why? Because it reminds them of Redux, the old one, not RTK. You know, we're also a bit Shell Shocked because of that. So so, yeah, Mark Ericson talked yesterday. So I do want to remind you that, yes, the old Redux is annoying and boilerplate, but, you know, Mark Ericson came back, cleaned it up and Redux toolkits actually really good. And it's fitting that he's the Simpsons character, so it fits with this meme. But yeah, useReducer is actually really useful, because you could useReducer and, you know, sort of compress those states.

Honestly, when I wrote this, I thought I was being clever and that this was a cool way to do it.

Play from 9:00

11:00 Let's also talk about use context, also a hook, that's…

But, okay, it does look a little bit weird. It makes a little more sense when you have a lot of use dates that you do compress to one. useReducer, and I will say that typing useReducer is a little bit painful, too. One really, really cool thing that I like using reducer for is, toggles, so doing a toggle with useReducer is actually the simplest thing ever. Because you just have this used reducer, you toggle a Boolean value. To true or false? And then you pass it directly to the event handler. So if you want a reason to use, useReducer, this is a great way to do it. Let's also talk about use context, also a hook, that's, it's really not too weird. The way that React was doing context before was definitely very weird. And you know, so you have context, you have a provider. And then you have the weird TypeScript thing that you have to do.

Whenever you create a context, you have to cast it as something super weird. But we're not talking about weird TypeScript things, we're talking about weird React things. And a lot of people think that use context is for states that rarely changes. But really, this is not the most accurate way of thinking about it. Because a lot of people will take that and say, like, Oh, I have authentication state or something like that. That's, you know, only going to change when they log in and log out, so they use context for that. And and then they realized, you know, oh, our app is really slow because changing that state is going to render everything under it. So instead, I would say and frame use context is more for dependency injection. It makes a lot more sense like that, and so when you do that, you end up having a component structure that looks like this.

And okay. This is, of course, one of the weird things about React. People like to make fun of it, but this is actually fine. All right, you know? And a lot of people actually have special components and special libraries that allow you to flatten this. But I think it looks pretty good. So, you know, maybe keep it like that. What's not cool is this? If you don't know what this is, that's a button down there, and these are everything that's used to render that button. And this is actually taken from source code from some company, which I won't name. But yeah, there's. There's a lot of props in there. And higher order components will do this, so please stay away from those. So, use context. One weird and awesome thing about it is it can be called conditionally. You could do. This with the use context hook, you could do this with the use hook. But you could basically say, you know, if something is true, use context.

Otherwise, you know, do something else. Which, you know, this might be a reminder to some of you, but you can't call most hooks conditionally. And, you know, accept in solid, you know, spell, whatever, like. They were able to figure that out, but with React, we have, you know, rules of hooks and things like that, and really, this does come down to how hooks work. Because, like random people on the internet have found out, you could actually sort of conditionally run a hook, because what a hook is doing is it's basically, just queuing up, hook calls. So you have maybe a use St and a useEffect in your custom hook. And so when it reruns component, it's checking those things again. So it does make it possible to have just dummy hooks that do absolutely nothing. And you know, now you could use a hook conditionally. Don't do this, but, if you're in dire need for a conditional hook, you, you could actually do this. So the rules of hooks are not really based on programming best practices, but more technical limitations of how they work.

All right, so let's jump into state now, we have two types of states local state, which is per components, and Global state, which is for your entire app. And so for simple updates, so you just want to update some data you have the useState hook for Global states use context debatable, but you know, you could use it for some Global state. For actual logic, that's where useReducer really helps, but for Global state and actual logic. This is where it gets questionable and where we have a lot of libraries that sort of fill that void. But in the React documentation, there is actually a really powerful hook that they don't really talk about too much, which is useSyncExternalStore, and this actually comes from the docs. It's one of those examples where if you have some sort of external store, you could use that connected to your components. And even pass that store through context.

And just have a really easy way of providing. Global states, you know, within your application, and it is, you know, found in the other hook category with a bunch of other useful hooks, too. For some reason, use imperative handle isn't shoved into there. But, I guess it's more important than using external store, um. But there are, of course, other libraries for doing this sort of global state things, such as Zustand, Redux, or also. XState store. So I created Xat, and we actually just released a library a couple months ago called XState store. That allows you to have a really simple Global state in React, or whichever other framework you want. All you do is define the context, and you define the way that the context changes. And that's pretty much it. Then you could also have, emitted events, and this becomes really useful. Because we'll get into my next favorite hook.

But it allows you to manage side effects, too, without having to actually call the side effect inside of your logic. So you could just emit those events and then listen to those events. So let's say you have a DUT shop. Basically, this is the way you use it. You could select from the doughnut store, so you could select from your context any sort of data that you want. And then you just send an events to update that, and then you could use that directly in your components. And then you could actually take those emitted events and react to them. So it's just a subscription, so you return the unsubscribed function to clean it up. And then whenever that event is emitted, you could react to it, such as showing a toast. And look at that. There is nothing in the dependency array because the store is defined outside, so React somehow knows that's always going to be stable. Which brings me to my next hook useEffect, and this is my favorite hook of all.

Because it's caused us so many problems. You know, first of all, you probably try to do something like this. Where es Lint, you know, hates you and it yells at you for, Hey, you forgot to add something, so you're like, Okay, fine, es lint? I'll just add this. And then you have an infinite. Loop, because it's like this onchanges an inline function, so it's always changing. So I'm sure some of you have written this before, and you know, you've lost when you've written that es Lin disable line that we have all pretty much written at least once. So in fact, search your code based. When I'm done with this talk, you're going to see, wow, I have like 40 different ES Lint disable calls and my Apple absolutely blow up. When Reacts 19 comes along. And then, I'm sure when we were starting out, this happened too. You know, we forgot the dependency array, and really, I wouldn't blame you. Because if you go to the old React docs and the section where it talks about skipping effects or using the dependency array is all the way down at the bottom.

So it introduces all of useEffect and a ton of stuff. And then at the very bottom it's like, well, actually, you know, you could use a dependency array? So yeah, and it, it's weird. Because React hooks were introduced in 2018. And the official docs, which are much, much better for explaining how to use the dependency array, when to useEffect ETC. They were created in 2023. So Reacts just has a long-term game plan for how it releases docks and releases updates, but, yeah, with React you, you just have to be patient. And then my favorite usage of useEffect, fetching data. This happens to be really, really common, you know? We're just like, Hey, fetching data is a side effect, so let's just put it in useEffect, and then we forget the dependency array. And Amazon or Versel is really happy because you're giving them all of your money. So what do we do? We have to write all of this boiler plate, where if you insist on writing, fetch calls and useEffect.

You probably have this under muscle memory. And you're like, Okay, I have to add is cancelled. Or, you know, if you're a more experienced dev, then you're like, Hey, I'm going to use a boards controller basically does the same thing, but you feel fancier, and then, or you could just have a canceled flag, but guess what? These will execute twice on Mount in strict mode, so maybe you'll disable strict. Mode or maybe you'll figure out the smart thing to do, which is to make your API calls item potent. But you know, most of you won't do that, so you'll probably just disable strict mode. So, you know, some people on the internet will say, Hey, you shouldn't fetch on useEffect, or some people will say, don't fetch at all. Like, chance. He did tell me that yesterday, so I captured it and I'm like, you said this, he does have a point, though. You could just use route loaders and things like that, um.

But even the React stocks itself say that. If you're using a framework, that framework's data fetching me mechanism will be a lot more efficient than putting your fetch calls in use. Effect. And so that's why you should, you know, fetch as you render, not like render, then fetch. That's something that you really want to avoid doing, but yeah. It's becoming more and more clear that with React 19 coming around the corner, there's a clear message. Which is use a framework server. Render and fetch in the routes, not in the components. And of course, most React apps today aren't really doing this. But yeah, that is why, you know, I strongly recommend if you're going to fetch in the component, at least use something like React query instead of fetching in useEffect. And I know some of you will tell me, like, yeah, but guess what? It's using under the scenes, it's using useEffect first of all, it's using it better than you.

Okay, Tanner Lindley knows what he's talking about, he knows what he's doing. You don't, and also not really. If you look at the source code, it's more relying on synchronizing with a query client, which is using sync external store.

Play from 11:00

22:00 Speaking of suspense, one of the reasons that's rea suspense, or…

There might be a couple of useEffects in there, but this is the main mechanism where, that Rex query is using. Okay, so, speaking of the double execution thing, in fact, this was noticed by some React query users. Where? If you wanted to lazily initialize something, you might use the initialize function of use date. Or another pattern that you could do is the U.M. The single ref or ref initialization technique, where you create a ref and then. If the ref... Curren doesn't exist only then do you create something? And so these might also execute twice. And in many scenarios, like using suspense or in an error boundary, this will actually happen. So this is another thing that you have to be wary of. Speaking of suspense, one of the reasons that's rea suspense, or, sorry, not React suspense. But React 19 is taking a little bit and might not be released for another few months or maybe next year.

Something happened where they changed the behavior of suspense, where, now it will wait for each item if you have multiple items or multiple children in a suspense component. It will wait for each one of those to finish fetching its data, and then it will continue with the other component, which completely changes the behavior. And, TK Dodo noticed this. I was at React Summit, he wore this sign, sort of in protest, like free suspense. He was very, very vocal against it. But thankfully they were able to reverse it. He mentioned state machines. So I showed up, but yeah, uh. Thankfully they got this fixed and the React core team did something that they don't usually do, which is admit that they were wrong. So this is going to, this is going to be changed. Thankfully, all right, I only have 9 minutes. So let's talk about other hooks.

Real quick. useRef is a really useful hook. If you want to do something but you don't want react to know about it, then you know, useRef. Sort of keep it, keep it away from React. But a lot of people do this. Annie pattern, actually, which is writing directly in rendering, like we saw with the initialized once pattern, or reading that ref value inside of. Like, just anywhere. So basically, while you're rendering, whether it's in the return of the or if it's, you know, anywhere before. And so this is actually an Annie pattern that a lot of people do. So, in es Lin rule will probably tell you that this is a wrong thing to do. But it is one of those weird things about React. You have to make sure that your render function is, is pure. And another really weird thing. I've always had a weird. Time with this, especially with TypeScript. Forward ref thankfully, forward ref is going away in Reacts 19, so we don't have to worry about that anymore.

Play from 22:00

25:00 You could try it out now, or you could actually selectively…

It it was weird that React was like, Hey, you're, you're not allowed to use this as a prop. It makes absolute sense. So this is one of those things that seems like an obvious change in React 19. All right, so let's talk about a couple more. Hooks use Meman useCallback, the hooks that we love to sprinkle all over our components just to make them faster. I, I don't even know why we do it, we just do it out of habit, but the problem with this is that it can very easily deopt and all the benefits of used memo sort of go out the window. Once you have things like inline objects, you know, for example, if we have an options object that we're passing in. Then. You know, you sort of have to do this to make sure that it, you know, it, is actually memorized, and it's just really painful. Memory cost goes up, too, so you're sort of doing a tradeoff over here. And a lot of people do this too. They useCallback, for an event handler, and then they pass that memoized event handler into on click.

Which is really only fine if you're, you know, if your component's expensive, and if you don't want, like, honestly, I would say start with this, just put a normal event handler. Instead of just, you know, trying to make a call back out of everything. So the main point is used memo and used callback should only be used if you're noticing a performance problem. And you need to actually memorize, some part of your app. So speaking of memorization, there is also reacts, forget and fun fact. A lot of reacts projects all start with the letter F. So instead of use call back and useMemo, you could use React forget. And it's sort of a compiler that allows you to, basically do the used call back and used memo stuff without having to do them. And you could try it out now, or you could actually selectively do it to certain components by putting used memo inside the component.

Play from 25:00

27:00 We have that used, used client, used server…

I didn't know. About this until two days ago. But yeah, we have that used, used client, used server, and now we have used memo, which, you know, it's pretty weird. But it's just JavaScript, it's just a string, it's harmless. Yeah, there's. I only have five minutes. So there's a few other hooks, that are of varying usefulness. Uh. Use transition and use deferred value, or S of remnants from concurrent mode. And so now it's for current features that maybe you'll actually use. And, there's also the use hook, which is coming in React 19, really, really useful hook, no pun intended. Unlike use imperative handle, which is underrated, but people never use it. It's okay, let's talk about the elephant in the room. PHP or RSC's, you know? And this was the used server, use client, stuff that I was talking about. RSC's are fairly recent. They were announced, you know, a few years ago. And then, Next.js decided, Hey, we're going to actually make them a core part of our framework.

RSC's are a little bit weird, too, because you would think that, all right. I have client components and I have server components. But, you think, oh, my client component is only going to run in the clients, right? Not really. So use clients really means, yes, it's going to run in the client, but it's also going to run in the server. Things become really confusing. There's a really hacky, weird workaround to make sure that your component only runs in the client, at least in Next.js. We're not going to go through that. But yeah, this is just really weird. So you have to do something like this. Be like, Hey, is window undefined? Okay, we'll read the inner width, otherwise, just put some sort of dummy value there. But guess what, next, at least next will'll yell at you that, this is a hydration error. These values don't match up. So you have to do more weird things where you have to actually useEffect.

And then you have this weird flash of showing nothing and then showing the window width, and it just becomes really, really confusing. So a better technique is that really useful hook? I was talking about USync external store, and so this allows you to actually provide the. Server value, which we could just set to zero, and the client value which is when do. inner width. And it. It actually makes things a lot easier. So I keep mentioning T TK Dodo, he's a really smart guy. So, he has an article on this and I really encourage you to read it. But yeah, honestly, a lot of the weird things about React you're seeing today are just Next.js declaring things as stable, which React is declaring as not stable. But they're just going with it and saying, like, Hey, you could use it now, even though it's not officially released yet.

So, yeah, it's just a little bit weird, but thankfully there's, I mean, there's more than just Next.js, there's, never mind, there's this Next.js that supports, React server components.

Play from 27:00

30:00 React is definitely really up there

All right, so overall, only have 3 minutes left. React is awesome, and you know, it is always a safe choice. No one ever got fired for choosing React, unless you've used this, then you probably have gotten fired. And React is definitely a very, very popular framework. I don't need to mention that to you. Just look at this graph of version numbers. React is definitely really up there. All right, sorry, I'll show you a better graph. This is React over here, and this is npm downloads overtime. I think over the last three or four years, this is the great view takeover of 2022 for some reason. And then, there's Angular, which is the x-axis. So yep, all right. So while I have just a couple minutes left, I want to just offer some, you know, maybe spicy takes? First of all, don't worry about the Cutting edge React stuff because, honestly, it's probably 5 years away anyway, and you really don't need to worry about most of the stuff.

The IDI idiomatic React that, you know in React 18. That's still going to apply, and 99% of your work will be done using the normal React knowledge that you know and that you're used to. So don't don't jump and try to learn the newest things, and also don't worry about silly things or the weird things that we talked about. Do you remember when we were talking about this? And we're like, Oh, we have to bind our event handlers. And do that. And now no one talks about this anymore. You know, that was just a huge waste of time. So just don't worry about stuff like that. This is not really a spicy take, so I put PGA over there, cuz P is not really that spicy. You all really don't like spicy stuff here. But read the docs seriously, because once you actually read the React docs, which hopefully most of you do, you realize that the weird parts really aren't that weird.

And of course, you could also read the source code, but maybe don't do that with React because the React source code is really weird. There's bit shifting, there's, fiber and lanes and all sorts of weird stuff. So, honestly, just read the docs, and really just make things that users want, like that's your goal. Again, you could use your existing React knowledge. Don't worry about the Cutting edge stuff, because really, all that matters is, are you able to do your job? Create awesome apps, create awesome user experiences? You know, users really don't care about the technical decisions that you make unless you're using Angular. Then this stuff shows up and, yeah, it becomes a little bit messy. But other than that, React is awesome, React is weird, and thank you so much React Al Cont for having me.

Play from 30:00

Related talks