Server Actions
- Server Actions are the actions that are performed on the server-side.
- Server Actions are used to fetch data from the server, perform calculations, and update the database.
- Server Actions are triggered by the client-side actions if your component is client side.
use-server
vs server-only
use-server
should force it, right? Yeah, thisuse-server
is a hint to the React compiler that this file should be ran in a NodeJS environment, basically.t's like, this should be ran in a NodeJS environment.It also hints at how, when you start composing components together like a client component with a server component,it hints to the compiler that, these things can't belong in this order.
You cannot import a server component into a client component, or something like that.
You cannot use an action, a server action without that server action being scoped inside of a use server directive.Either globally in the page or in a component,you could put use server at the top of the function you're making,which I think is a gross UI and you should pretty much always do this, in my opinion.
Syntax
- Define
use-server
in the top of the file can run on the server side and they make this as server action. revalidatePath
is used to revalidate the path after the server action is performed.mean if your path is/register
then it will revalidate the/register
path. and fetch the data again.
"use server";
import { revalidatePath } from "next/cache";
export const signUpUser = async (data: FormData) => {
console.log(data); // print the form data on the server console not in client side
revalidatePath("/register");
};
Usage
- Server Actions are used in the
action
attribute of the form tag. - When the form is submit the server action is called and user can signup.
import { signUpUser } from "@/app/lib/utils/action";
import React from "react";
const TestingTodo = async () => {
return (
<form action={signUpUser}>
<div>
<input
name={"todoName"}
id="newTodo"
type="text"
placeholder="Add todo"
className="border border-collapse"
/>
<button>Add</button>
</div>
</form>
);
};
export default TestingTodo;
Questions
Where Next.js Actions can runs?
Next.js Actions can run on the server a node environment where your app is deployed.
How to redirect on successful form submission on server actions?
You can use the redirect
function on server side actions to redirect to the specific path.
How to validate the form data?
You can use the yup
library or Zod
and make a client component to validate the form data. Remember to validate the form data on the server as well
How to Perform Authentication checks in Server Actions?
You can use cookies or JWT tokens to authenticate the user
import { revalidatePath } from "next/cache";
import { getCookie } from "@/app/lib/utils/cookie";
export const signUpUser = async (data: FormData) => {
const cookiesStore = cookies();
console.log(cookiesStore.get("next-auth.csrf-token")); // getting prisma cookie
console.log(cookiesStore.getAll()); // getting all cookies
console.log(data); // console form data
revalidatePath("/register");
};
What about condition error messages based on the error types?
You can used the props in the error.tsx | error.js
file to display the error messages based on the error types.
https://nextjs.org/docs/app/api-reference/file-conventions/error
Pages can blink when add new todo is there any way to prevent this? b/c i used to revalidate the path?
You can use the revalidatePath
function to revalidate the path after the server action is performed. It will fetch the data again and update the UI.
- The only way to avoid it is kind of what I said earlier.If you need your UI to update off of a server mutations,you're probably just use client instead.So I would just go back to what you were doing before server actions came and handle your mutations client side.And that way, you have more control.I think certain mutations are really, really good.For side effects and things that don't need where the UI is depending on a response.Because then you do have to ask yourself questions like that, well, how do I create really slick UI that doesn't like Flickr like that or something like that?
- Yeah, you could probably get around it.You could do some smart caching you could do.Some layout stuff like I'm sure you can figure out a way.But if you just did it on the client,you're probably just better off that way for now.Me personally, I'll probably use server access for like tracking analytics,stuff like that.Web hooks, things like that that happened in the background.But when it comes to UI, I'll probably still do client stuff for now.
It is better to use Next.js Routing which is file based, or custom routing?
you're not gonna use Next.js routing,you should probably not use Next.js. That's like the whole point of it.So yeah, if you don't want to use it or whatever, I would just use React or go look at another framework like Gatsby or Remix or something like that.
we're handling most of the data on the server side,do we still need state management libraries like Redux?
That's a great question.You would only need state management libraries like that on client components that needed state management.So, I'll give you an example to do form.
- I don't have to do this on a server.In fact, I personally probably wouldn't.I would probably do this on a client, so I would do a used state here.And do an on change on the input the traditional form.I would traditionally just do that because I wanna control over the UI.
- So yes, you will probably still need state management the other reason is that like state on the server is global.So every person shares the same state,assuming it's not in some serverless environment, at least in development mode.
If we have a server component inside it client and inside its server how is this loaded?
It's basically, it's going to be loaded in the order in which you rendered it, right?
- Actually, Next.js has a good example of this https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#interleaving-server-and-client-components
- You can only import a server component into another server component.But you can import a client component into a server component.
- If you want to import a server component into client then it work as a client component. the solution is that you can make a layout and then those layout is client-side & render the server component on that.
How to pass props client component to server component?
- You can pass props from client component to server component by using the
props
object. - You can also use the
useContext
hook to pass props from client component to server component. - You can also use the
useRouter
hook to pass props from client component to server component.