May 8th, 2024 × #react#server-components#forms
React Server Components: Form Actions + Server Actions
Discussion on using actions and form actions in React Server Components for calling server code from the client side without needing a separate API
- Introduction to React Server Components form actions and server actions
- Overview of form actions in React Server Components
- Discussion on what the server is in a vanilla React app using Server Components
- Explanation of actions in general beyond just form actions
- Examples of using actions beyond form submits
- Binding actions to form submit as well as other methods
- Introducing the useActionState hook for accessing action state
- Benefits of built-in pending state management
- The useFormStatus hook for accessing form submit status
- Passing data into actions like a normal function
- Running actions on the client vs server side
- Using the useOptimistic hook for optimistic UI updates
Transcript
Wes Bos
Welcome to syntax, folks. Today, we have another episode for you on React Vercel components. So we did episode 718 as an introduction to React server components, and now we're going to do another one specifically on actions in React server and components. So form actions, server actions actions, whatever you're gonna call them. We'll explain all of that JS being able to call server code or run code on the client without having to do a whole bunch of extra work is honestly a game changer. I'm a big fan of the this idea of actions in in React server components.
Wes Bos
So it's not even just Vercel. A lot of this is client side stuff as Wes. And we're gonna Scott of dig into it, explain how it works, a lot of the use cases and whatnot, so buckle on up. How you doing today, Scott?
Introduction to React Server Components form actions and server actions
Wes Bos
Doing great. We are, right about to head out to Miami tomorrow, Westside. I don't know when you're heading out, but my family's heading out there, and we're bringing the whole crew along. So, hey, I'm stoked. We've never been. I'm sure the kids are gonna have a blast going to museums and whatever they're gonna be off doing. But you and I are gonna be at React Miami, which by the time you're hearing this JS long and gone, but pretty stoked to be out there. So, yeah, excited.
Wes Bos
Yeah. It's been been a while since I've been to a conference probably about 6 months or so. So and it, like, seems like everyone JS really stoked about this one as well. Wes seems like a really fun one, so I can't wait. It's a somewhat busy conference season for me this year. I'm doing
Wes Bos
JS nation.
Wes Bos
I'm doing, React Miami and then potentially doing another one. We're gonna see if I can make it out to Utah. There's 1 in a parks Park City at React Rally.
Wes Bos
So I'm Oh, yeah. Gonna see if I can do that or not. But yeah. And in November, we are going to be in New York City doing, another live syntax as well. So Yeah. And potentially another something else as well. Pretty stacked. It's gonna be pretty fun. And if you are, you know, sending data back and forth, you're, you know, working with forms, you're working with data of any kind. Sometimes that that transmission, whether that is via the UI or the server, you know, these lines are getting blurred, and your tools really need to get blurred as well. And that's why we use something called a Sentry, which is what the show is presented by, to track all of our data and how it works inside of our app. We look for slow queries. We look for slow routes. We look for slow form events and those types of things. And we're able to track at any given point if something went wrong in that process regardless if it was happening on the server or the client or that kind of fuzzy area in between that now exists given how these tools work. So if you want error handling, exception handling, all kinds of, instant replay bug finding tools, Head on over to century.ioforward/syntax ESLint up and get 2 months for free.
Overview of form actions in React Server Components
Wes Bos
Alright, Wes. Form actions.
Wes Bos
I don't know that much about React Vercel components beyond what we've talked about.
Wes Bos
I get the general vibe. And in fact, go back and listen to episode number 718. That's, syntax.fmforward/718 if you wanna learn more about React Vercel components in general.
Wes Bos
But, you know, working with data is a big part of these things. Most websites, what they do, they load data.
Wes Bos
They allow you to interact with the site.
Wes Bos
And many times when you're interacting with the site, you're sending data back to the server, then data comes from the server back to the ESLint. And that whole process is something you do a 100 times. You know? If if you're building anything, you do that a lot Yeah. Especially if it's interactive.
Wes Bos
So I'm interested to hear exactly how form actions in React Vercel components compared to the things that I'm familiar with, but also, how they make my life easier.
Wes Bos
Yes. I'm very excited about this, and I should say that everything we are talking about today is a 100% React.
Wes Bos
It's not a Next JS stuff. There's one little thing I'm gonna talk about at the very end in regards to caching and invalidating data that is in Next. Js specific, but everything we're talking about today is just React, meaning that it will be and and already is implemented in
Wes Bos
vanilla React JS well as all the the the frameworks that are out there. So And a a question with that, though, Wes. Yeah. When you say vanilla React in this regard, what is the server component there in a vanilla React app in 2024?
Wes Bos
Server components is kind of a a funny word, in that because Oh, I don't I don't even necessarily mean
Wes Bos
the component as in, like, a React component, but, like, what is the server
Wes Bos
of a Yeah. Vanilla React site if you're not using something like this? What is the server? Yeah. The server can be anything. It can be a server that is running React on the server. It can be a build step. So, like, React server components don't necessarily need a server.
Wes Bos
They can be prerendered as as part of a build step instead of actually being on the server, which is kind of interesting.
Wes Bos
But, generally, yeah, you're going to reach for a a framework that implements the whole server thing for you, whether that is Remix. We're gonna start seeing stuff from them pretty soon on their React server components.
Wes Bos
Next. Js, obviously, is first to the party there, but there's a whole bunch of other sort of projects that are are working on this right now. One of them, which I'm really excited to see, is the tan stack stuff. So he's he's been, like, chewing on this for probably a Yarn now. I talked to him about, Reactathon last year, about it, and he's just like, not totally sure. And it it seems like he's he's really has some ideas for how how this should work. So what is a server? It it depends.
Wes Bos
It depends. And you can you can implement it yourself as well with with Vite,
Discussion on what the server is in a vanilla React app using Server Components
Wes Bos
but it's, again, it's still early days for that type of thing. That's the hardest part for me with any of this is when we're saying this is in Vanilla React. It's like, what is the server there? The I wonder if there ever becomes a point, which I kind of doubt at this point, but, like and we got all this React server stuff. Would React ever ship their own server?
Wes Bos
Yeah. That that's a great question. And the answer to that is is maybe. I like, I I don't know if they will, but the kind of interesting thing is that a lot of the stuff that we're talking about it, server render components, form actions, server actions, All of that stuff is being added to React, which is something, like, I feel like I've been asking for that forever. You know? I've been asking for easier way to do forms.
Wes Bos
You're like the way to do forms in React before this is, like, you gotta do your own state. You gotta listen for update functions. You have you gotta, like, set Scott, and you have initial state. And, like, it's just like, why is this so hard that I need to reach for a third party library to do it straight away. Like, why the one thing that we do so much in this thing is is have forms and submit them. Why is that not a first party thing? And and now it is. Now it is. It's it's absolutely beautiful. So I'm pretty excited that this is being added, and it's not something that we'd leave up to framework land. So let's talk about it. Actions.
Explanation of actions in general beyond just form actions
Wes Bos
They are often you're gonna hear the word form action, and you're gonna hear the word server action thrown around.
Wes Bos
But we're gonna start peeled back a little bit from forms, actions, and server actions, and we're just gonna call them actions. Right? Because actions are functions that can be run whenever likely Wes a form is submitted. Right? Like, the the hugest use case for Vercel actions to form actions is when you submit a form and you want to run some code.
Wes Bos
This is going to be replacing a lot of your submit logic that you've had, which I was just saying, and they can run either client side or server side. So these are not just if this is not entirely for sending data to the server and getting stuff back, it can just run entirely client side, which is a very common use case Wes, alright, I have this form or I have this UI. And when somebody does something, I need to run a function that will generate some state. So I see, like, 2 huge benefits.
Wes Bos
Personally, I've I've built a couple things with them already. I have a couple sites in production using them. I see, like, sort of 2 huge benefits to this type of thing. JS first, you actions allow you to tie state, which is your data, your submit handler logic, like, what happens when somebody clicks a button or submits a form, and pending, which is often people use, like, use transition for to to create, like, a pending state.
Wes Bos
Often, you are cobbling together your logic, your state, your pending into, like, a use effect or or using a third party library.
Wes Bos
Actions allow you to sort of put that all together into a single function. And then the second huge benefit here is that it allows you to call server side code from the client without any sort of APIs. And and that's the massive benefit to me is that you can wire up a button that says save user, have a user type into a form input, click that button, and you can bind that button to a function that runs on your server side. That function has database logic validation, anything that you would normally do on a server without having to do a GraphQL API, a REST API, you know, like, all of the the overhead of of that type of thing. So it's a a massive productivity boost to be able to have, like, a RPC, which means remote procedural call. Being able to call server side code from the client is is such a benefit. I feel like I can just prototype stuff so much faster in React, and, of course, like, all of the other meta frameworks have this idea as well as just, like, on on the Svelte SvelteKit site for syntax, we have all kinds of buttons in the admin area where you just click on the button, and it runs some code server side and and can relay the status and the pending directly to the client.
Wes Bos
Yeah. And and that was even the 1st time I saw anything like that was in Remix, and I I I remember trying those types of things and just being like, yes. This is what I've wanted. You know? Yeah. I I'm used to calling Mongo commands from the client in Meteor. So for me, like, our PC feels very great, and I know that some people feel skeptical because they they have been working in a a different flow for so long. But there's definitely a lot of just generally nice things that can come about, especially if your client and server are a little bit more, like, I wanna say tightly coupled. You know? For a little while, we swung into this world where everybody's blog had its own API. And, like, hey. If there's not, like, multiple things consuming your API, why do you have an API that so tightly, Wes so, you know, not coupled to your to your UI? Is that ever going to be a thing you'll actually need?
Wes Bos
Totally.
Wes Bos
So actions, they're often tied to a form submit, but they do not have to be.
Wes Bos
Sometimes, some examples of what you might want to use an action for JS, at the very basic, you want to have somebody click a button and increment a number by 1. Right? Like, that's the the very that's the hello world of Mhmm. State management is incrementing.
Examples of using actions beyond form submits
Wes Bos
You might wanna add an item to Yarn. When somebody clicks on an add to cart button, that might go to the server and add an item to the cart, it might just be entirely client side where you have, like, some state that is somebody's cart and you wanna add an item to it. You might all like a post, take your email in, and subscribe to a newsletter, send some metadata about like, for example, if you are listening to this podcast and you reach every 15 seconds, there's a progress event that gets fired by the audio element. Right? You might want to send that data to the server Node, or you might want to log that data to local storage so that if somebody wants to reinstate it, you can save that data. It pretty much the whole crud thing. Right? Create, read, update, delete Yep. Of being able to map those functions to your validation and your database logic on the server is quite honestly the hugest benefit here, and and that's what I think most people are going to be using them for.
Wes Bos
Word. I I have a question. Can you use these things outside of a server component? Can these be done in a client component? Oh, yeah.
Wes Bos
They can be run anywhere. Okay. Meaning Client side server side, but also Sometimes your actions are going to be server only, meaning that they have the database logic inside of them. And sometimes your actions are going to be need to be run on the client because it's it's something that only needs to happen inside of the browser because it is based on events, or it doesn't doesn't have to go to the server. Right? Like, there's a lot of stuff that happens only in the browser, and they can be totally done like that. So, yeah, they Sanity run anywhere.
Wes Bos
Like a drag and drop might be a a good example of of something like that. Yeah.
Wes Bos
Using actions. Here's my next point. Actions can be called anywhere, but the most likely are going to be called in these 3 areas. 1, on a form submit. You pass an action to the action action to the action attribute of a form element. So you have a form element. You have your you normally have an action that points to a URL on your server.
Binding actions to form submit as well as other methods
Wes Bos
What this will allow you to do is you can say action equals curly bracket, and you pass it the reference to the function that you've imported. And, again, that that function can be either some client side code that needs to happen when somebody submits that form, or it can be some server side code that happens when somebody submits the form, and they will progressively fall back. What's the word for that type thing? Or progressive enhanced, meaning that if you turn JavaScript off, they still will work Yeah. Because they they have been bound to that.
Wes Bos
And I do wanna say, I think this may be a thing even more in the React world than outside of it. Mhmm. Forms.
Wes Bos
Forms are a key component. If you're sending data around, hey, man. Forms. I I know a lot of React folks just use buttons or even worse like a DIV. Click send an event because it's easy. You Node, just send a fetch with a a button or something like that. But, hey, forms are forms are great. And, if your page is server side rendered and you have a form, it will still work. Yes. It's it's beautiful,
Wes Bos
that you can use forms. That's also what I like so much about this API is that it is built on forms and form data, meaning that you don't have to maintain state in JavaScript in order to send data to the server.
Wes Bos
Yeah. Back to the, back to the web. You know?
Wes Bos
That's the first one, form submit. The second 1 is you might wanna call it programmatically, in an event handler. Right? So you use something like downshift to to create a a combo Bos, and you type something. And when somebody hits enter on an item in the combo box, you might wanna programmatically submit that event handler. So you that's the example of it doesn't have to be tied to a form. That's why they're not just called form actions. They're just called actions. And then the third one is in like, you could you could also run them in a useEffect. So if you have some other code that is sort of watching for a a specific change and you wanna you wanna submit this action whenever that item changes, you can Node up a custom useEffect to to do that. So they're not called form actions? They're not called form actions. They are called
Wes Bos
actions. Actions. Alright. And actions are functions. I'm laughing because the episode title form actions and server So I was
Wes Bos
Yes. That's I I I didn't wanna call it just actions because I know. If you when you see them being used in documentation and everywhere, they're either called server actions or they're called form actions. So but they're they are just called actions, and then we'll talk about what form and server actions are in just a sec. Yeah. Can I actually just say even quickly?
Wes Bos
It's a huge missed opportunity to not call them reactions.
Wes Bos
I mean Oh. Come on.
Wes Bos
You're right.
Wes Bos
Damn. That's that's a good one. Oh, that's maybe that's like a good library if somebody wants to build a library that sits on top of this.
Wes Bos
Reusable, composable, react actions for common use cases. Got it. I like it. Perfect.
Wes Bos
Using actions. So now in order to use an actual action, you can, like I said, pass them to a form's action attribute.
Introducing the useActionState hook for accessing action state
Wes Bos
But if you want a little bit more control, you're going to use 1 or or all of the following hooks. So the first Node is the use action state hook.
Wes Bos
This was previously in in today, if you go to the React docs, it's going to say use form state.
Wes Bos
Mhmm. And that has changed because partially because of of some comments I put on the GitHub, partially because of they talked to Ryan Florence from, Remix about like, it was kinda funky. Like, I was, like, learning it, and I was like, this seems odd Wes in order to get the status of if like, is it pending or not? Like, is it currently being sent to the server and coming back? In order to get that data and in order to call it, it was 2 separate hooks.
Wes Bos
And they couldn't you couldn't put them in the same component because one of them had to go inside of a form, and one of them has to go above the form. And it's just like Wow. Yeah. That doesn't make any sense to me. So I, like, I I wrote some comments on GitHub, and the React team reacted to it.
Wes Bos
And they changed the API to use action state, which is much better in my opinion. I'm really excited about this. So use action state is a hook.
Wes Bos
You pass it your action, and it's going to return to you 3 things.
Wes Bos
First, the state of the action, and this could be a few things. So once you call an action, it it either does something on the client side or it goes to the server side, and it's gonna return to you some data. Right? And that could be success messages. It could be, some error validation that needs to be displayed to the user.
Wes Bos
It might be previous form state or initial state.
Wes Bos
So if you are trying to read like, you you filled out a form, didn't work, you wanna do it again, you can get the the data from the previous submit.
Wes Bos
Or initial state is if you wanna prepopulate some of the inputs in a in an action, you can do that with the use action state. So the initial state is the first argument, Then you have the bound action itself so that you would you would pass that action to the the form or the button click or the programmatic event handler. And then the third one is, most importantly, the pending state. So this is going to be a Boolean of is this action currently running? And because actions are asynchronous, they you can await inside of them. Likely, you're going to be doing something like await database Scott save. Mhmm. You might be fetching an external API, things like that. Right? And if that promise is currently pending, then you probably wanna do things like disable the 4 the field set or disable a button or show a spinner or, like, any number of things you wanna do while something is, currently pending. So it gives you a nice Boolean, and then you can use that Boolean anywhere in your page to display whatever it is you want. Like, for example, I was throwing up a toast message when it was pending saying, like, saving blah blah blah blah. Mhmm. And then when when the data came back in the the first argument that I talked about, then I would update that Toast message to say, item blah blah blah saved.
Wes Bos
Yeah. And that's really great because the alternative for that is you create your own state variable.
Benefits of built-in pending state management
Wes Bos
You set it to loading JS equal to true, right, when you click that Yes. That form, and then you said loading is equal to false on the state whenever it's returned. So this just gives you a nice little helper Sanity handy little bit for that. You know, one thing I really do love about this flow is the error message validation stuff Because, you know, one of the things that working with forms, bad UX, people don't get right all the time.
Wes Bos
Form error messages validation.
Wes Bos
You Node, something went wrong in the server process returned, and maybe the form isn't responding the correct way. This makes it so easy to get that right because JS all you have to do is make sure your your server returns a proper error message with whatever you want to say, and your forms become super reusable because you can have a if error, check for error message, just display the error. I do this all the time in in Svelte form action. So, you know, I I think this is a big win for a lot of, like, easy accessibility.
Wes Bos
Yeah. I actually hooked this up with, Drizzle Node Mhmm. And it was beautiful because I created my schema in Drizzle for the database, and then I got my types out of that, and then I use Drizzle Node to also do the validation for it. And then I was able to send any errors to the client and line them up with the input. You know, sometimes you you fill out a form, and it just tells you at the top of the form what your errors Yarn, and then some nice forms will highlight the actual field that is invalid.
Wes Bos
That is much nicer. I did find myself leaning a lot more on just like HTML validation because of the whole sometimes you don't your whole form is not a client component. It's maybe it's just a server component, but it's, it was a really nice flow to be able to do that type of thing. And I'll, shout out Alex Alex dot j s on Twitter. He's the creator of t r p c. He's doing a ton of research in this area right now of, like, how do you make a good form library with this? And you don't need a form library, but he's he's sort of, like, looking like, what are the patterns gonna start to look like Wes if you wanna make a reusable bunch of components. What what does that look like? Yeah. Totally.
Wes Bos
Next hook we have here is use form status.
The useFormStatus hook for accessing form submit status
Wes Bos
This will this is a hook that allows you to access if the form is being submitted. It must be used inside of a form element, and this will give you the information of if it's being if it's pending, so you might wanna use that to, again, disable inputs, show a spinner. This previously was the only way to get information of if a form is being submitted or not, and that was a bit of a pain. So you might not even need this one if you don't need it because you could also just pass this data down via props, but you you do have access to it. It doesn't you don't need to pass it down. You could put this. I think the idea is that you're gonna have a single button component that you can use in any form. And if you wanna make a reusable submit button component, you can use the use form status hook to figure out if its parent form, whatever it is, is currently being submitted via the pending state. It also gives you access to the form data object itself, the method, which I I can't figure out why you would you need that in action as well.
Wes Bos
Yeah.
Wes Bos
Hey. More more info is not not a problem, but yeah. Yeah. Yeah.
Wes Bos
Next, let's talk about actions themselves and and their their input. So just like a function, an action, whether it's a server action, whether it's a client action, whether it's a form action, can take in any data that you want. So most of the time, if you hook up an action to a form element, you're going to get a form data object. A form data object is, if you're not familiar with it, is a JavaScript API for you can take an entire form with all of its inputs and and all of the data that the user has taken in. You can convert that entire form to a a beautiful object and have all of the the data that you want. What this will do is you have access to that whole object, and you can then pass that data into your your database saves or whatever it is that you're gonna do.
Passing data into actions like a normal function
Wes Bos
So for many cases, you no longer have to use Scott, form handlers on change, on input, default value, that annoying error where it's like there's no change handler tied to this or whatever that error was. I hated that one. You just pop a form on the page, give your inputs names and attributes.
Wes Bos
And when you submit the form, your action will receive a form data object, and you can use it however you wish. You can also programmatically pass other data to it if you want as well. If you're not using it with a form, you're just using it programmatically.
Wes Bos
You can it's just a it's just a function. Like, actions are just functions, and you can use them with the hooks to to get some of this additional functionality.
Running actions on the client vs server side
Wes Bos
So actions, like I said, they can run server or on the client.
Wes Bos
And how do you tell React that you only want this code to run on the server? Because like I said earlier, the killer feature of this is being able to write a function with server side code in it. You can put raw SQL statements inside of this function.
Wes Bos
You can export it from a file, go into a client component, import it in, and just say, on submit or action equals save user. And just like that, like, being able to go from the server to the ESLint, of course, if your your whole stack is in JavaScript. I'm curious if there will ever be, like, a a PHP adaptation to this. Mhmm. But being able to just jump from server to client like Meteor did, like, 15 years ago is is absolutely beautiful. So the way that you mark a function as being server only is by either inside of the action itself, And then when I say action, it's a function.
Wes Bos
You write the words use server in quotes, and that marks that function as a server only function, And that will make sure that that code is never run client side. It's not gonna import any of your server dependencies on the client Node. And Next. Js has really good errors around this type of thing where it says that you're trying to do this and you shouldn't have. What's more likely is you're gonna have, like, a, like, a lib folder with all of your functions inside of that. And every single file inside of there, you're just gonna put use server at the top of the file. Mhmm. And that marks that whole file as code that should only ever be run on the server. So, usually, I'll have, like, an actions dot ts file, Yarn it as a user server at the top, and then you write all of your updater functions and and queries inside of that.
Wes Bos
Yeah. That that I think that, like you mentioned, just moving them to a separate file is probably for the best. I know people will colocate and that will be a thing. But that makes a lot of sense in terms of organization and making sure you're not leaking anything. I Node that's a concern.
Wes Bos
One thing that really bugs me is when people talk about this stuff in the context of PHP, and they're like, well, this is just PHP. It's like, well, call me when PHP is a client side scripting language as well because it's really giving us the best parts of PHP without,
Wes Bos
you know, being able to maintain the the client side aspect as well. So Yeah. Yeah. It's really nice. And the the I think one thing that trips a lot of people up is that server components by default, if you do not put a used client in that file, that file is by default server only. Mhmm. And if you put a function in that file, so you have a server component file, you put a function in there, It will also be run on the client side. So you have to mark client components with use client, and you have to mark server actions with use server.
Wes Bos
And for a lot of people, they're always like, oh, that's stupid. It's a kind of a a funny way to do it because components are server by default.
Wes Bos
And if you want to run a component on the client, you have to market with used client. But if you wanna run an action only server side, you have to market with used server. Right? It seems a bit a bit bizarre, but they're part of it is like a security thing where you have to explicitly mark something as a used server. The reason we have that is because you're you're crossing the boundary from server to ESLint, and you're you're connecting the 2.
Wes Bos
And if you want to do something that is client side, like put it in an event handler, but you want the code to run server side, you have to explicitly mark them with that used server. So little bit of a funky thing to to sort of get getting used to, but it starts to make sense after a little bit of a while.
Wes Bos
What do we got next here? Let's talk about optimistic state. So another, hook we have here is called the use optimistic.
Wes Bos
Scott, do you wanna give a quick explanation of what Optimistic UI is?
Using the useOptimistic hook for optimistic UI updates
Wes Bos
Yeah. So Optimistic UI is you know, the word optimistic here comes from the fact that you are optimistically thinking that this server side action that you're doing will be successful. Right? So let's say you are you you have, like, a to do list. You submit that to do list in an ideal situation that to do typically goes to the server, gets loaded in the database, and then that gets populated probably into your UI, like a typical to do list. Right? It would pop up and and, you know, that server process can take some time. There's a round trip there, and users are you know, when they click something and it doesn't happen instantly, your users might try to click it again. That might think your app is broken. Your app is gonna feel slow. On a bad network, that's going to take even longer, and it's going to feel bad.
Wes Bos
So optimistic UI is the process of saying, hey.
Wes Bos
I feel like this thing is going to succeed, and, therefore, I'm going to update the UI immediately with the success state. So even without getting the server database storage of that to do was successful, you're still populating that to do into your UI instantly.
Wes Bos
Therefore, the UI feels very snappy.
Wes Bos
And in a situation where that would then fail, you gotta handle that. So it would remove it from the UI or it would give an error message. There's various ways to handle that. But, basically, the optimistic part of this whole thing is that you're handling your UI as if your server calls optimistically are going through.
Wes Bos
Yes. That's a great explanation of that type of thing. And I love when apps have, like, an optimistic UI because you don't have to, like, sit there and wait even if it's 2, 300 milliseconds. Like, a good example is if you just have a to do list or or a chat app, right, in in Slack. As soon as I hit enter in Slack, it's sent. Right? 99.999% of the time, that message is going to be sent. Right? And Slack will render it out as if it was sent, but they will also provide a little bit of UI being, like, like, it's not actually sent. Like, it looks like it's sent for you, but maybe it's great text. Yeah. Maybe there's a little spinner beside it. Maybe nothing. You know? Maybe they just show it, and if there is
Wes Bos
a failure, then they'll show some sort of UI to you. But Or maybe it tries again. Wes. Yeah. Yeah. Yeah. Yeah. Retry as well. Yeah. We do this in my habit tracker because that was a whole thing. You'd click it, and on a network conditions that weren't great, it wouldn't necessarily even look like it was clicked. And you might click it again. That causes a whole host of issues. So, yeah, optimistic UI, it it really helps your applications.
Wes Bos
It's like cheating to feel faster. It's a a great technique. Yeah.
Wes Bos
So use optimistic works with your actions that you already have, and the way that it works is it takes in 2 things. It takes in 1, your state.
Wes Bos
So your state might be if if we're talking about a chat application, it might be an array of message that have been sent. So it takes in your existing state of the messages, and then it also takes in your your action that needs to be submitted once somebody types in the box and hits enter. Right? From that action, you get 2 things. You get your state with any optimistic state added to it, and you get a method for adding new optimistic messages. So the idea here is that use optimistic is going to proxy your state and give you a method for optimistically adding on to that state. So your your actual state is a list of 5 messages, and your optimistic state is a list of 6 messages.
Wes Bos
And when you go from that 5 to 6 and you hit enter, you immediately optimistically add that new state to it as well as you could you could throw a flag in there called pending or something like that if you wanna show that it is currently pending, and then you go ahead and submit your your action. And that optimistic state understands that there is an action being submitted inside of it.
Wes Bos
And once that action has successfully resolved, then you're back to a spot where your optimistic state and your actual state are the exact same thing. So there's only ever a little bit of time in between where your optimistic state and your actual state are going to be different. And, with all of the examples that I've seen so far, there's very few examples out there of people using this already.
Wes Bos
Usually, what people are doing is just throwing the entire trying to replicate what it looks like that would come back from the server, and but then throwing an extra flag variable on there being like, this is pending or this is optimistic.
Wes Bos
And then that way you can show a spinner or something like that. What I have not found is any patterns for showing how to, like, roll it back.
Wes Bos
You know? Like, what does that Mhmm. Look like when it fails?
Wes Bos
That was something that Apollo did really well. Yes. For GraphQL. They had nice docs for optimistic rollbacks.
Wes Bos
I've done that myself, but Yeah. It's kind of a tricky, UX thing in general because of what you do. You pop it out of the ESLint. You resubmit. Like, there are UX considerations there that I think are a little bit more,
Wes Bos
I don't know, a little bit more deep than just, hey, do it for me. You know? Exactly. I think that's why it doesn't do any of that. Yeah. I'd assume so. Because you have to put that own logic in in your action. So, again, the way that this will generally work is that you take your your existing action and you call that action from within your new optimistic action, and the logic of what to do when it fails and retries will be coded into your your optimistic action. So instead of taking your your existing server action and piping it directly into a form input, you're sort of wrapping it in you're wrapping both your state and your your action in use optimistic hook, and then that will allow you to add your custom logic in there and proxy through your optimistic state.
Wes Bos
So that is action. Everything we've touched upon so far is React only. It pairs really well with working with caches.
Wes Bos
So we're seeing Next. Js has this idea of a cache and a cache clearing, and what that will allow you to do is if you have a list of 7 items on a page and one of your actions is to update or delete one of those items or to add a new one, you always get into this weird situation where especially with pagination where okay. Well, that now is done.
Wes Bos
I need to refetch the data that is on that page. In in in SvelteKit, we we have this as Wes, and and I think the SvelteKit approach is just it invalidates the entire page and just sort of, like, re fetches all of the data on that page. I think that's right. Is that right, Scott?
Wes Bos
Yeah. You know, there's you could do it different ways. Like, you could push into an array instead of just grabbing a whole new array of data. I think grabbing a whole new array of data is fine. But, yeah, we're just doing we're just invalidating the page or that specific data
Wes Bos
with a query param. Oh, yeah. So the Next. Js approach to this is currently, it's just like a URL or a a route to invalidate, which I don't love because I don't know what page I'm on. When I'm writing a component, the the server action doesn't come with the current page that you're on, so it's kinda hard to do that type of thing. However, the new they have, like, this unstable cache API, which is much better.
Wes Bos
And the way that that works is you can tag your caches with a bunch of different tags. Like, you could say, like, items item page 2, items sports, and then you can then invalidate a tag. You say wherever these items are being used in the cache right Node, that just blow them out and and refetch them. And and that API to me is is awesome because most likely what you're gonna do is somebody's gonna submit a form that either creates a new item, updates an item, or deletes an item, and you're going to want to say, alright. Well, I saved it.
Wes Bos
Now what I want to tell the client to do is refetch
Wes Bos
the list of items that are on that specific page, and that API is is pretty slick. Yeah. Yeah. And it it's you're right. That's 90% of the time what you're gonna maybe 99% of the time what you're gonna be doing here. So cool. Well, that that was super informative. You Node? I think this sort of world where we're talking about actions, whether that, you know, is the the Remix flavor of it, the Svelte flavor of it, or now the React Vercel components or React flavor of it is the right direction for me. This is the direction that I have been waiting for. And React for, I think, for a long time, it's kind of been on the we're making things hard for you kind of position for a lot of this, especially in regards to form handling and things like that. So for me, this is a step in the right direction for React. It's making something easier for me. Yeah. That's that's where I wanna be in React land. I want it I want it to get easier because hey. We we have powerful tools. Now let's make these powerful tools, friendlier tools.
Wes Bos
Big fan.
Wes Bos
Let's get into sick picks. What do you got for me today?
Wes Bos
Yeah. We are headed to over well, we're headed to Amsterdam, and we're going to Florence and stuff because I'm I'm speaking over there. And so we're doing a little bit of a a 2 week vacation to bounce around Europe for a little bit. And one thing, when you have kids, you have car seats.
Wes Bos
How are you gonna do that with, kids in car seats? Well, that's not going to work very Wes. So we got these inflatable car seats, Wes. They're good. They're like booster chairs. Our kids are old enough for booster chairs, so they're not like the car seat that you put a 2 year old in. Yeah. Yep. Yeah. I'm calling it a car seat, but it's a booster seat because our kids have graduated to those. But you have an inflatable booster seat. How you gonna blow this thing up? Well, Courtney got these little miniature air this little miniature air pump. It's tiny.
Wes Bos
It's this little Tolinski little air pump. And I have, like, a a portable air pump that's about this big that's USB powered. But this thing is literally, like, this big. And, it has a built in battery, so you charge it up and it can blow up an air mattress and all kinds of stuff. But specifically for us, we're gonna be using it if we're renting a car or maybe we're even taking a taxi or something.
Wes Bos
We need to be able to quickly inflate these booster seats, deflate them, whatever.
Wes Bos
And it's just a little $23 little air pump. What a Wes what a wild world.
Wes Bos
I just remember, like, you'd be, like, pumping it by hand. We'd be you know? But, yeah, this tiny little pump is is really pretty amazing. We gave it a try last night for the 1st time and really stoked about it. So, check it out. It's a tiny portable ultra mini air pump.
Wes Bos
Works really well. That's awesome. You it's wild how motor technology has improved in the last couple years because you're you're starting to see products like this, like a tiny little pump. You're starting to see, like, the opposite, which is, like, people have luggage that you can suck the air out of the luggage so it compresses more, and that's you can now do that because you can put a you can put a tiny little pump inside of luggage, or you're seeing these tiny little blowers that are, like, super powerful or, like like, Dyson hairdryer knockoffs that are relatively affordable because, like, motors and fans and pumps have gotten yeah. And batteries as well. It's just, like, being able to pack a decent sized battery life in them. So, like, the the motors are getting more efficient, the batteries are getting better, and you're starting to see all these really interesting new products.
Wes Bos
Yeah. I'm going to sick pick the AVerMedia live streamer cap 4 k.
Wes Bos
So who The name.
Wes Bos
This is a, basically, an alternative to a cam link. So I have been chasing some frame rate gremlins.
Wes Bos
This did not fix that. It was it's a Chrome issue at the end of the day, but I decided to keep this because the cam link 4 k is a pain in the butt because it is USB a, and it's like a dongle. So if you're plugging a heavy HDMI into the Cam Link 4 k, and then you're trying to plug that into like, then you have to plug it ESLint, like I don't have USB on my MacBook, so you Scott have a converter or you plug it into a GitHub. And then the Cam Link 4 k doesn't work with Thunderbolt 4 hubs, so you can't plug it into the hub. So I I did a little bit of research, and this is the one that a lot of people are recommending. It's cheaper than the Cam Tolinski 4 k. It's a Bos, so it's Scott a dongle. Right? It has an input and output. You just use any USB c cable or not any USB c cable, but, like, a good USB c cable.
Wes Bos
And I'm I'm thinking about just mounting it directly to the camera itself.
Wes Bos
Yeah. So that wherever I go, I just sort of have it, and it's been awesome. It's 60 frames a second on 10 80 p and 30 frames a second on 4 k, which JS, I think, the same as the cam link as well. Plug and play. It's been working great.
Wes Bos
And, also, like, the other thing is, like, whenever I would open up my photo booth on Mac OS X or o what's it called? Mac OS Mac OS. Yeah. Yeah. I would have to, like, change to a different camera and then back to the Cam Link to get it to work for whatever reason.
Wes Bos
So there's just, like, little gremlins with the Cam Link that I was I was having. Not enough to be too much of an issue, but if you don't have something and you're looking at buying it, the Cam Link 4 k has been out for, like, 8 years and hasn't been updated. This thing is this this thing is awesome. Good. Really affordable, and it works really well. I've been I ran it for, I don't know, probably 30 hours straight. I also tested a bunch of the Amazon, like, knock off ones just because, like, I had Node lying around because it's, like, $20 as, like, a backup.
Wes Bos
The color on it is there's there's I think there's light, but the color is awful. Yeah. Yeah. Like, I didn't think that that would matter. You know? But I don't know how how video compression works.
Wes Bos
Yeah. Also, I don't necessarily know how capture cards work. I I had no idea you would have done anything, like, affecting color, but I guess that's why you do not go with the cheapos.
Wes Bos
Yeah. I guess because it needs to change it from an HDMI stream to Mhmm. Whatever a webcam is looking for. So it it literally has to do something there's chips in them. That's why they're expensive. Right? It's not just a a converter where wires get connected to wires. So I was I was impressed that or I was surprised that the the knockoff one looks so terrible.
Wes Bos
Work. Cool. Well, I I like this. You know, I I have 1 cam link 4 k and 1 cam link that's, like, a 1000000000 years old. So maybe I should upgrade my non four k one to, something that does 4 k as well considering camera size. So yeah.
Wes Bos
Alright. That's it for today. Anything else?
Wes Bos
No. Thanks so much, Wes. I thought this was really, really super great. Yeah. I I look forward to giving all this stuff a rip.
Wes Bos
Alright. Peace.