How To Use Next.js 14 Server Actions

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up YouTube today we are going to go over server actions and how you can Implement them inside of your nextjs 13 or 14 project before we do that if you can hit that like button and also subscribe for more content just like this that'll be greatly appreciated but other than that let's jump right into it so as you can see on my screen I have the nextjs docs open inside of the server action section if you want you can pause the video and read through the docs other than that let's talk about what server actions are and why you should use them so server actions actually integrate react actions for a built-in solution for Server mutations and server mutations allow you to update your database either by creating new documents deleting documents updating them or reading them and you could do this all within the same component so if we scroll over to the next page um this is how server actions work so instead of manually creating API endpoints like you did in the past instead you just Define find a synchronous server function directly inside of your component this will make all of your code in one area making it more organized and clean and then server actions can also be defined in server components or they can be called from the client component so now let's jump into the code and see how all this works so what we have here is we have the code on the left and the development server on the right and on the left let's go over the code so what we are using is NEX js14 and this is a server component and that is by default and we are using prism as the orm and mongodb as the database if you want to learn about these two specific subjects I do have videos on this on my YouTube channel so go check those out but this is a server action video so let's just talk about server actions and things related so what I'm doing is I'm calling the database and storing all of the expenses inside of the expenses variable on line seven and then we are just mapping through all the expenses and list listing the name and the amount as you can see here in our development server so this like I said is a server component so the next step I want to do is I want to mutate the data I want to add more expenses to this expense tracker and the way to do that is pretty much back in the day is you would call an API route from your backend and then your back end will request the data from the database and then push it back to the client page but now with server actions you could do it all in one place but before we get into server actions let's go over the old way of calling and mutating data like we did with client components so first off right above the UL we are going to have a form and inside this form we're going to have an input two inputs and then a button just like this and what you'll do in the past is you would put on the form and onsubmit and you'll call function whatever you want to name it add expense and then we will create the function above the return as an asynchronous function and then we're going to get an error thrown at us saying we can't use this event handler because this isn't a client component so what you have to do in the past even if you use xjs is you have to mark this whole page as a used client and the directive it will be at the top right here so it'll look just like this and like I said this is the old way of doing it and now after you do that you will just await you'll wait and then you'll do a fetch request to your backend API endpoint whatever it is and then you'll do like a post request and then passing all the data and stringifying it through just like this and then you also set up an backend API folder inside of this specific path right here and then you'll call the database so there's a lot of steps to this and server actions make this a lot simpler so we're going to remove this for now remove the used client directive and we are going to remove the on submit so that is the old way of doing it now server actions allow us to do everything inside the server component and mutate the data inside of this specific file so instead of on submit we're going to have action and then this action is going to call the add expense function like this so now we got to create the ad expense function and what we are going to do is we're going to mark this as a used server inside of this code block just like that and then instead of taking in the event action by default allows us to take in the form data on forms so it's going to be form data and the type is going to be form data if you're using typescript just like that so now we have no errors we refresh the page everything looks good now we can do our server mutation right inside of this code but first we need to get the values and what I'm going to do is I am just going to um change up these inputs and labels inside my form to match what I have on this right here so let me just copy this over real quick contrl Z so what I did is I pretty much have an input with a type of text I have a name attribute a placeholder a class name and required for two different inputs as you can see here and the way you get the values from these inputs is by storing them in a variable so we could call this expense name and then we're using the form data doget method and we just put the name whatever we have here there so now we're storing in this variable and let's do for the other input as well which is expense amount so now we have the two values inside of these variables now let's do the server mutation inside of the server action so what we could do here is we could just say cons expense equals await and this is how you create a new document inside of mongodb using prism and it'll be name and amount and now we're getting typescript errors because name is says it could be null so we're going to say this is as string and this one it says it could be null and this is a type number so we're just going to put the number like this and then put everything in parentheses and now all of our tyar should be gone and this allows us to do a server mutation on the actual component itself and this whole file is a server component so let's test this out to make sure everything's working so I'm going to make this bigger I'm going to inspect the page and we're going to go to the network tab we're going to try to add an expense here so we're going to say we went to Chipotle and it cost us $10 and we're going to click add expense and now we're going to look over here the network Tab and we get a 200 um request status code of 200 it's a post request and is making a call to this endpoint right here even though we didn't create the endpoint we're using a server action so it looks like everything worked but the only thing is the form has not reset and then also the the UI hasn't updated so let's refresh the page and now you can see Chipotle $10 is here so there's a few problems when we run into this one is the form needs to rev validate so let's go over that so let's minimize this again and it let's actually revalidate all of the data and the reason why that this Chipotle $10 didn't actually get updated when I submitted it is because xjs caches all of the request so on line seven right here this request is just going to keep fetching the same request unless you revalidate the data so to do that you have to import the revalidate at the top revalidate path at the top of your component so it's going to look like this and that's from next slash and we can do this inside of the add expense function so we're just going to reval validate the path of whatever the path name is which in my case is the expense tracker as you can see here in the URL so now let's try this again let's save the code and this should allow us to update the UI when we actually submit whatever the expense is so let's say we went to the bar and we spent 25 bucks we click add expense and as you can see it automatically updates the unordered list with a new listed item right here because we are revalidating all of the request inside of this component so that is how you use server actions inside of server components like I said we run into a few problems the form isn't resetting so let's fix that to make the user experience a lot better we must be able to reset the form and the only way to do that is using client side interactivity so as you can see after you submit the bar $25 it still stays there this should be reset so the way we are going to fix this is we have to actually make some changes to our code and refactor the code so we can actually Implement server actions and use client side code so if we go back to the docs and we're going to make this a little bigger as you can see the server action section with client components you can create your server action in a safe separate file with the used server directive at the top of the file then you import the server action into your your client component so that's what we're going to do now so as you can see in the example we are going to create an actions folder even though they don't and then an action file inside of that and then you must Mark the Ed server directive at the top and then you could Define your server action here and then you could import it into a client component as you can see here so this is a client component and we are importing the server action into here and then you could still use it inside of the form in a CL component so that is what we're going to do there's a quick example but let's go over that real quick so let's make this half and half go back to our development server and like I said we need to refactor some of our code so I'm going to make this bigger too and what we're going to do is we're going to move the form into its own component so to do that inside of the components folder we're going to create a form. TSX we'll do rafc which is the es7 snippet we can remove the import from react at the top we're going to go back we're going to cut the form and then we're going to paste it inside of the return and then what we're going to do here let's make sure we import the button which is in the components folder and then we could remove the add expense inside of the action so like the example showed is we must Define the action inside its own file and then we could import it here at the top and then push it inside of this action to actually use the server action so what we could do here is we could create an anonymous function so we're going to have an async and it's going to be form data it'll be an arrow function with some code block and then we are going to await the function name we're going to call so we had to create a function inside the server action file called add expense and then we're passing in the form data there so so let's do this and what we're doing here is we are refactoring the code and let's also Mark the form as a used client so we can actually reset the form because it does use client side interactivity and then let's go back to our page and where we remove the form let's import the form from this new component just like this so there we go just like that so now let's create a new folder called Act actions and inside the actions let's create a new file and you can name the same thing I'm just going to call this form action. TS just like that and inside the form action. TS let's mark the top as a use server and this is where the server action and all the logic is going to be done and this is for client side interactivity using server actions so let's import prism client from at prism client and let's make sure we get the revalidate path so it could update the UI and that's from next slash and then let's make sure we initialize prism client just like this new prism client let's create the function export cons add expense this is going to be an async function let's close the code block and this is going to take in the form data right and the type is form data let's make this a capital 2 just like that and what we're going to do is we're going to grab the values the same way we did with the server which is going to be expense name name and this is going to be form data. the expense name and then we're going to have the expense amount which looks exactly the same we did earlier and what we're going to do here is then we're going to mutate the data right because this is where our server action is so we're going to say cons expense equals and then we're going to create it right here and this is going to be expenses like this Mark this one as a string and then this one as a number because we need to make sure the types are right because this is typescript and the last step we're going to do here is we're going to revalidate the path and this path we are going to revalidate is going to be still the expense tracker perfect so that is how your server action looks and this must be created in a use server component but we want to import it inside of this client component so we could still do that so we're going to say import at expense like that from actions SL form action which we just created and then it's going to be right here so let's just make sure this is working before we keep going let me um make sure these pages are side by side let's refresh and as you can see nothing changed let's add another expense let's say we got a tent from Walmart for 20 bucks add expense and tent for 20 bucks still pops up so everything works still the same we just refactored the code into different components to make this work but like you said the form is still not um pretty much resetting which is a bad user experience so to reset the form we have to go to the client component right which is this form right here so let me remove this and that and then in right below the add expense we are going to have a different import and we are going to import use ref this is going to allow us to manipulate the form to reset it without rendering the page so we're going to take the ref. current and then a question mark Dot and then we're just going to use the reset prop function just like that and then what we need to do here is we're getting an error because it can't find the name so we're going to say ref equals ref like that and then I have to initialize it as well which I totally forgot so we're going to say cons ref equals use ref and it'll be an HTML form element and we're going to have the initial value is null and then we're going to have ref equals ref and the ref. current. reset so this allows us to reset the form and it had to be a client component that's the only way we could use this react hook so let's try something else let's try dinner dinner $50 we click add expense the form resets and it adds the expense down here perfect so everything is working the reset form is working and the server action is still working as well without making calls the API endpoint now the next thing I want to do to make this even better is when you click add expense I want to have a loading state so it's just say like loading when it's loading and then when the expense gets added the loading will go away the form will reset and then the add expense bun will be back to normal adding a loading uh loader inside of this application is very simple and if you actually go through the docs of nextjs it tells you exactly what to use I mean there's multiple ways you could do it you could probably use use state but there is even better way so if I make this a full size page and if I scroll down go to forms am mutations and then there is a section about displaying loading state right here and it is recommending that we use the used form status hook to show a loading State when a form is submitting on the server and the used form status hole can only be used as a child of a form element using a server action and then it gives you example right here of how you could use it and then how we can implement it in our code so let's show half of the screen again open up our code and we are going to go to the button component so inside of the button component let's make this bigger we have just the add expense so what I want to do here is make sure you have the button as a used client because it is client side interactivity and we want to import a hook which is what they recommended which is the use form status and this is from react Dom and what we're going to do here is inside of the used form status we can access the pending state so right here just like that so you're going to say cons pending equals the use form status and then what we're going to do here is in the button we're going to have a dynamic value so we're going to say if pending is true we could say adding just like that and if it's not true we're going to say at expense so that is the text of the button depending on the state that we get from the Ed form status so this allows us to actually see and use whatever the status is of our server action so we're going to copy this area disabled and we're going to add it to our bun as well so we're going to disable the button if the status is pending as well so I'm going to remove this right here and now let's test our code so we are going to just move this over make this bigger let's refresh the page and let's add another expense so this expense could be school supplies we're going to say 30 bucks and if we click add expense it says adding and then add expense and then it adds right here let's do another one so we could say um XBox 400 bucks click it it says adding and then it adds the expense so that is a loading State and makes the user experience a lot better so those are the main topics I want to go over when it comes to server actions that is how you could use it on a form and how you should be able to implement it inside of your nextjs 13 or 14 application if this video has helped you in any way like I said the beginning hit that like button and also subscribe for more content and if you do have any questions just leave them down in the comments and hope to see you guys soon
Info
Channel: Brett Westwood - Software Engineer
Views: 23,613
Rating: undefined out of 5
Keywords: server actions, nextjs, next js 13, next.js 14, how to use server actions, using server actions in next.js 14, useFormStatus, Server, next js server actions, next 13 server actions, nextjs server actions, server actions next js, server actions react query, next js 14 what's new, next js 14 roadmap, next js 14 tutorial
Id: 5MRLO-7O2So
Channel Id: undefined
Length: 21min 6sec (1266 seconds)
Published: Wed Nov 08 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.