Forem

Nelson chege
Nelson chege

Posted on • Edited on

working with Server Actions

Server actions were introduced in NextJs version 13.4 in Alpha together with turbopack (Beta) and App router(stable).

They have a good developer Experience when using them plus other features that are really nice to have.

with server actions:

  • allows progressive Enhancement which allows forms to function correctly without javascript
  • you can now you forms inside of server action, reducing the amount of javascript shipped to the client
  • you don't need to create other endpoints todo mutations. (but these actions are considered as api endpoints by nextjs)

Because at the moment,server Actions is still in Alpha, you have to add this to your next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverActions: true,
  },
};

module.exports = nextConfig;
Enter fullscreen mode Exit fullscreen mode

now creating a simple form that calls an action

import { addTodo } from "../lib/actions";
const AddTodo = () => {
  return (
    <div>
      <form action={addTodo}>
        <div className="">
          <input
            type="text"
            name="todo"
            required
          />
        </div>
        <div>
          <button
            type="submit"
           >
            Submit
          </button>
        </div>
      </form>
    </div>
  );
};

export default AddTodo;
Enter fullscreen mode Exit fullscreen mode

server actions can be imported and saved in a separate file making them cool to work with.

the "use server" must be included on top of the file

"use server";

import { randomUUID } from "crypto";
import { revalidatePath } from "next/cache";

export async function addTodo(data: FormData) {
  const todo = data.get("todo");

  await fetch("http://localhost:3500/todos", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      todo,
      userId: randomUUID,
    }),
  });

  revalidatePath("/");
}
Enter fullscreen mode Exit fullscreen mode

inside the Action you are able to do all the things that a normal API endpoint used to handle such as communicating to a database

the revalidatePath will update the cache with the new data add to the specified path.

And thats all required to get started using server actions.

An extra feature that can be included inside server action is the useTransition hook.
This provides pending and startTransitions to play around with. you can disable the button using the pending status.

"use client";

import React, { useRef, useTransition } from "react";

type AddTodoFormProps = { addTodo: (todo: string) => Promise<void> };

const AddTodoForm = ({ addTodo }: AddTodoFormProps) => {
  const todoRef = useRef<HTMLInputElement>(null);
  let [pending, startTransition] = useTransition();
  return (
    <>
      <div className="">
        <input
          ref={todoRef}
          type="text"
          id="todo"
          name="todo"
          required
        />
      </div>
      <div>
        <button
          disabled={pending}
          onClick={async () => {
            startTransition(async () => {
              await addTodo(todoRef.current!.value);
            });
          }}
        >
          Submit
        </button>
      </div>
    </>
  );
};

export default AddTodoForm;
Enter fullscreen mode Exit fullscreen mode

for the action, data passed to the action will only be that one variable

"use server";

import { randomUUID } from "crypto";
import { revalidatePath } from "next/cache";

export async function addTodo(data: string) {
  const todo = data;
  const payload = {
    todo,
    userId: randomUUID(),
    createdAt: new Date(new Date()).toLocaleString(),
  };

  await fetch("http://localhost:3500/todos", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  });

  revalidatePath("/");
}
Enter fullscreen mode Exit fullscreen mode

conclusion

server actions is an easier way to communicate with your backend without extra endpoints and also reduce the javascript code that is passed to the client side.

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay