Check out a free preview of the full Introduction to Next.js 13+, v3 course
The "Server Action Mutation" Lesson is part of the full, Introduction to Next.js 13+, v3 course featured in this preview video. Here's what you'd learn in this lesson:
Scott demonstrates the process of updating server data using server actions. This segment also covers invoking Server Actions outside of forms, buttons, or inputs by utilizing the startTransition function provided by the useTransition hook.
Transcript from the "Server Action Mutation" Lesson
[00:00:00]
>> Yeah, we left off on all the server action stuff, which was, like I said, kinda crazy this. So this is one of the newer things that they released in the latest version of Next.js, which is what prompted me to wanna come back and teach the course again.
[00:00:12]
And I felt that it was substantial enough that I wanted people to know about it. So, it sounds like that I resonated of a lot of people, hopefully if you're watching this, you thought this was pretty cool, I think so. It's one of those things that it's a new way of doing something, kind of like when JSX came to the scene.
[00:00:27]
So, very curious to see what other frameworks are gonna do with this type of technology. Not just React-based frameworks, but other frontend frameworks. Now that server components is a thing, is it gonna stick around? Are people gonna like it? Who knows? So far, I'm enjoying it, but like I said, it's not for everything.
[00:00:45]
You don't wanna just use server actions for everything. I think in the Next.js docs, they encourage you to use it for every form that you have, and stuff like that. And you probably can't get away with it, but, I probably won't use it for that. [LAUGH] Like I said, unless it's for like a side effect, that's pretty much only my use case.
[00:01:04]
Cool, okay, so we have that. Let's talk about being able to do an update, and being able to delete one of these, just to kind of nail it home with the server action. So, all we can do is we can go to the todo, and we can create a another server action here.
[00:01:23]
But because the todo itself is not a form, we can't add the server action to the form action, because the todo is not a form. So we have to figure out another way to trigger a server action, and that's what we're gonna try now. So, in order to do that, we have to turn this into a client.
[00:01:43]
And this is what I said earlier, like if you can't use a server action as a form action, you pretty much have to use a client component to trigger that, and at that point, Mazal just do client side. JavaScript to do whatever you're gonna do, but we're going to stick with it, cuz I wanna show you the new stuff.
[00:02:00]
If you've ever made an API call on React, you already know that anyway, so I'm not really gonna show you anything useful there. So what we wanna do is we wanna import the { useTransition } from 'react'. So, useTransition is a hook that basically, you can give it some function to run, some async thing, mostly data loading, and React will deprioritize that.
[00:02:26]
It will, you're basically telling React like this is not a priority right now, finish all the other important stuff you were doing first, before you do this. Like do this right when you're done. And we wanna do that because we don't want whatever we're about to do to block everything else that's happening on our app.
[00:02:47]
We don't wanna clog that process, so we're gonna deprioritize. That's the best way I can describe it. I'm sure there's a better definition for it somewhere, but that's the best way I can describe it, so, yeah, we'll do that. Let me just go to that thing here, make sure I have that, okay, cool.
[00:03:05]
So, what we're gonna do now is go to our Actions, and let's just make a new function here, and we'll call it, completeTodo. So this is just a function you will run to complete a Todo, so, complete Todo, like this. Because this is not gonna run on a form, it's gonna run on whatever we want it to run.
[00:03:28]
We can take in whatever argument we want, so I'm just gonna take in an ID here, and then I'm gonna use db to find and update that. So then I'll just say, await, db.todo, make sure this is async, db.todo. Let's see, update, or, hmm, is it update? Yeah, I think it's update.
[00:03:56]
So let's update, where id is id, and the data we wanna update is gonna be complete, completed, true. So, go find a Todo, whose id is whatever id they passed in, and update it to complete it true. All right, so we got that, and then after we're done, we just wanna revalidate the path, so we can actually see, we're gonna make some UI changes when you complete it.
[00:04:36]
We'll put like a strike-through or something like that when something is completed, so we'll do that. So we got that, complete Todo, Then we can go to the actual Todo. We can bring that in, CompleteTodo, like so. And then, we're just gonna get this hook from useTransition like this, and then we'll get something called like isPending, if the transition is pending, and then we can get the startTransition.
[00:05:23]
So then, what I wanna do is on click, I run a function here, and I'm gonna say, start the transition, which takes a function. And then I'm going to say, CompleteTodo. CompleteTodo, and then pass in the todo.id. So, onClick is gonna take a callback, which calls startTransition, which takes a callback, which calls completeTodo, and pass in the todo.id.
[00:06:03]
Right? And then what I wanna do is just add some styling here, so add a class name. Let's just give this a border black, 10%, sorry, yeah, 10%, or 20%, and then we can say something like, let's do this, and make this dynamic We can say if todo.completed, then we can say strike-through, I think it's strike-through, we'll look it up on Tailwind, let's see.
[00:06:56]
No, it's like, text decoration? Text strike-through?
>> Yeah, line-through.
>> Line-through, okay, that makes sense, let's see. It's text decoration, okay, so, yeah, you're right, line-through, there we go. So, line-through, And maybe we'll change the color of it. So it's like grayed out, so line-through, and then text-gray-100, or that's way too gray, text-gray like 900 or something like that.
[00:07:36]
Okay, and what's this thing freaking out about? We need the, and if not, it's just a empty string, there we go, Okay, so let's see what happens with this, if we try to do a transition here. So we'll do that, we'll go over to our app, we have this, and let me put a cursor on this, it's bothering me.
[00:08:05]
So, pointer, or is it just cursor? Let's look it up. Cursor pointer, that's what it is. Come here, let me copy you, thank you. Cursor pointer, so when you hover over it, you can click on it. And now, if I go here and click on one of them, you can see it completes it.
[00:08:36]
If I refresh, It's still there. So that's just us using a server mutation for updating, and then revalidating it and watching it it actually change. Any questions on that? So again, you could do this client side, you already know how to do this client side, you make a API call.
[00:09:00]
The only thing you don't know how to do is how to make the API, we will do that though. Cool. Yeah, I just wanna show you how you can do server actions anywhere in any component, without using a form. That's how you do it. And this way, you can also do optimistic updates, where you can show the update immediately before it comes back, and stuff like that.
[00:09:26]
That's also a thing. But yeah, that's how you do that.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops