Next.js Server Actions... 5 awesome things you can do

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
just yesterday nexjs announced that the app directory is now stable and ready for use in production this is JS app full that's great news but what's more exciting is they just announced a new feature called server actions which allows you to write one-off server-side functions right alongside your server components and that's huge because it means you no longer need to write individual API routes when submitting forms or doing any other kind of data mutation in today's video you'll learn five different ways to use nexjs server actions and in the process we'll build a form that you can edit with real data that has a skeleton loading UI between updates and will also throw in a like button with optimistic updates and you'll be amazed at how much easier this code is to write with server actions but first not everybody is convinced on Twitter people have been roasting this feature because at first glance it looks so similar to PHP where you might have an index PHP file that co-locates your HTML with different server-side endpoints and that's totally correct but at the same time it completely misses the point when you run a server action with next it doesn't completely reload the page like a traditional PHP app would and instead only re-renders the server components that means you can create an awesome front-end experience with react while easily integrating server-side code as you may know I like to throw a lot of shade at react but honestly I think server components combined with actions is one of the coolest things they've ever done it's a classic react feature huge productivity boost with plenty of ways to shoot yourself in the foot it'll be easier if I just show you so let's go ahead and generate a new next application and by the way this video is part of my brand new Next js13 course which you can now access on fireship i o it contains over 30 fast-paced videos covering a bunch of different rendering data fetching and caching strategies the first thing you'll likely want to use server actions for is to handle form submissions that update some data in your database in this demo we have a dynamic route under dog slash ID which displays a card with some profile information under that Dynamic route we have another page that contains a form to edit this data prior to actions the way you would do this is to create an API route somewhere that uses a post or put request to run the actual mutation then you would create a client component that makes a fetch call to that endpoint then on top of that to show the updates in the page you'll need to bring in the use transition Hook from react until the client-side router to refresh the page it's way more complicated than it should be luckily actions change all that currently here in our edit form we're first fetching data in the server component and for the database I'm using versel's new key value database but feel free to use whatever data source you'd like once we have our data which is just a dog object with a name image and breed we can then use it as the default values here in the form on the form itself we don't use the client-side on submit event handler we instead pass it in action this is a special property that takes a function and will provide the data from the form to run server-side code let's go ahead and Define that function right here in the component body create an async function named up dog that receives the form data as an argument but you might be wondering what's up dog not much what's going on with you dog I'm just working on the server function here that's special because it has this use server directive next.js will automatically turn this into a server-side endpoint and you can access things like headers and cookies here if needed in this case we'll take our form data and update the database and that's literally all you need to create a mutation if we go into the browser and open up an the network Tab and then submit the form you'll notice that it sends a request to the URL that we're currently on it's a post request that runs that function we just defined on the server that's pretty cool but you'll notice that it doesn't automatically update the UI that's not ideal you'll likely want to show the latest data after the mutation is complete but we can easily fix that by importing revalidate path from next cache which will tell it to revalidate the page and update the server components but what makes this so awesome is that it automatically updates the data that we fetched in the UI it doesn't need a full page reload in addition we can easily Implement loading UI by simply adding a loading component to this directory and now when we run the mutation we get the skeleton UI that's displayed while the mutation is taking place I'm not going to cover the CSS for the skeleton UI but you can find it in the full course notes that may or may not be desirable in the UI but let's just take a moment to appreciate how easy it was to implement compared to previous versions of next the second thing you need to know is that you can use multiple actions on the same form currently updog is our default form action but let's go ahead and add a second button to this form but give this one the form action property that points to a completely different server function this function will also update the database but instead it will use next navigation to redirect back to the main profile page so it's like a save and quit feature but you could really do anything you want here like upload an image or update an individual form field or whatever now if we go back to the demo we have two different ways to submit the same form that's pretty cool but the third thing you should know is that server actions are composable and that means we don't need to Define them directly inside the server component it's often useful to Define them there because they can access other data that you've already fetched but you could just as easily extract them outside the component or put them in a completely different file for example we might create an actions.ts file that exports multiple server functions one benefit of doing this is that we can just put the use server directive at the top and it will apply to all the functions in this file but more importantly we can now reuse these actions in any component that's pretty cool but the fourth thing you should know is that the action property only works on elements inside of a form because server components can't handle clients side interactions like button clicks however it is still possible to trigger server actions from client components in this example we have two server actions of like and dislike that will increment and decrement a value in the database and then revalidate that path then from there we have a client component called likes it Imports the like and dislike actions from that file and also the use transition Hook from react use transition is essential here because it allows us to update State without blocking the UI what that means in this case is that it will execute the server action then the next JS router will reload the server component and update the state all in a single round trip to make that happen we have this somewhat ugly code here where we need to wrap the server action inside of start transition but once that's done we can now go back to our component and click the button which will run the mutation but also refetch the latest light count from the parent server component and does so all in one round trip which would be way more complex to handle without server components you'd likely need to bring in use effect in a client component and you'll probably end up losing your mind in the process in fact one of my favorite things about server components in general is they eliminate the need to use use effect in most of your components but the fifth thing you should know is that actions can also support optimistic updates one problem with our current implementation is that when you click the button there's like a few hundred millisecond delay before the light count actually updates and that's not ideal tools like Firebase have been doing optimistic updates for the last 10 years to make it appear like the server has zero latency I'm going to go ahead and re-implement our like button but this time instead of use transition I'm going to bring in an experimental hook called use optimistic this Hook is basically like a combination of use transition and use reducer in react it'll update the UI instantly with what you think the server is going to respond with then when the server actually does respond it will sync up the True Value usually that would mean there was some kind of server error and so it rolls back to the previous value in this component we'll also pass in the light count from the server component and then we'll add an additional property of sending so we know when the actual update is taking place from there we Define a reducer function that takes the previous state and then updates it with the latest value now from here we go into the click handlers for our buttons and we call the server action just like we did previously but we also use the hook to update a value that we think the light count will be which in this case would be the current light count plus or minus one and now if we go to the demo we can compare the two like buttons side by side you'll notice that in the optimistic button the light count changes as soon as we click it and that'll make your server look extremely fast even though it's not as of today server actions are in Alpha but they open the door to all kinds of awesome patterns if you want to get really good at next 13 check out my full Pro course where we'll continue to explore the possibilities with server actions thanks for watching and I will see you in the next one
Info
Channel: Beyond Fireship
Views: 258,266
Rating: undefined out of 5
Keywords:
Id: O94ESaJtHtM
Channel Id: undefined
Length: 7min 50sec (470 seconds)
Published: Fri May 05 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.