우선 Server Action 을 하기전에 우리가 항상 해오던 방식으로 접근해 보자!
// api/users/route.ts
import { NextResponse } from "next/server";
const DB = [
{ id: 1, name: "won" },
{ id: 2, name: "woong" },
];
export async function GET(request: Request) {
const searchParmas = new URL(request.url).searchParams;
const name = searchParmas.get("name") as string;
return NextResponse.json({
users: DB.filter((user) => user.name.includes(name)),
});
}
api 경우 request 시 query 값을 본 후 반환 해주는 로직이다.
// users/page.tsx
'use client';
import { useEffect, useState } from "react";
export default function UsersPage() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch(`/api/users?name=${'wo'}`)
.then((res) => res.json())
.then((result) => setUsers(result.users))
},[])
return (
<main>
<h1>Users</h1>
{users.map((user) => (
<p key={user.id}>{user.name}</p>
))}
</main>
)
}
위의 경우 평상시 api 호출 방법을 기재해 놓은 것입니다
// app/actions/user-acitons.ts
"use server";
export async function searchUsers(name: string) {
const DB = [
{ id: 1, name: "won" },
{ id: 2, name: "woong" },
];
return DB.filter((user) => user.name.includes(name));
}
파일을 작성 해준뒤 client 에서 사용해 보겠습니다.
'use client';
import { useEffect, useState } from "react";
import { searchUsers } from "../actions/user-actions";
export default function UsersPage() {
const [users, setUsers] = useState([]);
useEffect(() => {
searchUsers('wo').then(data => setUsers(data))
},[])
return (
<main>
<h1>Users</h1>
{users.map((user) => (
<p key={user.id}>{user.name}</p>
))}
</main>
)
}
가운데 fetch 부분을 삭제 후, 작성해 준 searchUsers 를 import 하여 바로 사용해 줄 수가 있다. 이렇게 간단함 덕분에 별도에 api 구현을 하지 않고 server action 을 사용하고 있습니다.