쿼리스트링, Link와서버 액션에 대하여
쿼리스트링 : 단순한 URL이 아닌 '페이지의 상태'를 담는 그릇
URL 뒤에 붙는 ?key=value 형태의 문자열인 쿼리스트링(Query String)은 단순히 서버에 데이터를 전달하는 것이 아닌 페이지의 현재 상태를 정의하는 명세서입니다.
- /board?page=2 → "게시판의 2페이지 상태"
- /products?category=food&sort=popular → "식품 카테고리에서 인기순으로 정렬된 상태"
쿼리스트링을 활용하면 사용자는 특정 상태의 페이지를 북마크하거나 다른 사람에게 공유가 가능합니다.
예를 들어, 내가 필터링한 쇼핑몰 검색 결과를 친구에게 링크 하나로 전달해 줄 수 있습니다.
& (AND) 연산자와 OR 표현
- &는 여러 조건을 동시에 만족(AND)시킬 때 사용합니다. category=food 그리고 sort=popular.
- OR 조건은 보통 같은 키를 반복해서 사용합니다. color=red&color=blue는 빨간색이거나 파란색인 상품을 찾는 요청입니다.
쿼리스트링은 서버와 클라이언트가 "페이지의 어떤 상태를 보여줄지"에 대해 소통하는 약속입니다.
<Link> 와 <a>
Next.js에서 사용할 수 있는 페이지 이동 방법입니다. <a> 태그 대신 <Link> 컴포넌트를 쓰는 이유에 대한 표 입니다.
구분 |
Next.js <Link> |
HTML <a> 태그 |
핵심 |
클라이언트 사이드 내비게이션 |
서버 사이드 내비게이션 |
동작 |
페이지 전체를 새로고침하지 않고, 바뀌는 부분만 교체 |
서버에 새 페이지를 요청하여 문서 전체를 새로고침 |
경험 |
앱처럼 부드럽고 빠름 |
웹페이지가 깜빡이며 로딩됨 |
<Link>는 새로고침 없이 새로고칩니다. 사용자가 <Link>를 클릭하면, Next.js는 이미 브라우저에 있는 자바스크립트를 사용해 다음 페이지의 필요한 부분만 가져와 교체합니다. 사용자는 훨씬 빠르고 쾌적한 경험을 하게 됩니다.
그러나, <a> 태그는 전통적인 방식으로 서버에 새로운 HTML 문서를 요청하고 페이지 전체를 다시 그립니다. 외부 사이트로 연결할 때가 아니라면, Next.js 프로젝트 내부에서의 페이지 이동은 항상 <Link>를 사용하는 것이 정답입니다. 새로고침은 사용자 경험을 해치므로 <Link>를 지향해야 합니다.
서버 액션 : <form>의 변경, API가 필요 없는 데이터 제출
전통적으로 우리는 <form>으로 데이터를 제출하기 위해 별도의 API 엔드포인트(/api/create-post)를 만들고, fetch로 요청을 보내는 복잡한 과정을 거쳤으나, Next.js의 서버 액션(Server Actions)은 이 모든 것을 한 번에 해결합니다.
서버 액션
클라이언트 컴포넌트에서 서버의 함수를 마치 내 함수처럼 직접 호출하게 해주는 기술입니다.
기존 방식:
Form (Client) → fetch → API Route (Server) → DB
서버 액션 방식:
Form (Client) → Server Function (Server) → DB
중간의 API 라우트와 fetch 가 대체되었습니다. 코드는 더 단순해집니다.
// components/PostForm.tsx
// 'use client'
import { createPost } from '@/app/actions'; // 서버 액션 함수 임포트
export function PostForm() {
return (
<form action={createPost}> // action에 함수를 직접 바인딩
<input type="text" name="title" />
<textarea name="content" />
<button type="submit">글쓰기</button>
</form>
);
}
// app/actions.ts
'use server'; // 이 파일의 함수들은 서버에서만 실행됨
import { redirect } from 'next/navigation';
import { prisma } from '@/lib/prisma';
export async function createPost(formData: FormData) {
const title = formData.get('title') as string;
const content = formData.get('content') as string;
// DB에 데이터 저장
await prisma.post.create({ data: { title, content } });
// 작업 완료 후 게시판 페이지로 이동
redirect('/board');
}
<form>의 action에 URL 대신 함수를 직접 넘겨주면 Next.js가 나머지를 알아서 처리합니다. 페이지 새로고침 없이 데이터를 제출하고 작업이 끝나면 redirect를 통해 다른 페이지로 부드럽게 이동합니다. method="POST" 같은 속성도 사용하지 않습니다.
이는 기존에 알던 API의 POST와는 다른 Next.js에서 사용하는 새로운 데이터 제출 방식입니다.
정리
오늘 정리한 세 가지 개념은 Next.js가 개발자 경험(DX)과 사용자 경험(UX)을 동시에 향상시키는 것을 보여줍니다.
쿼리스트링으로 페이지의 상태를 명확히 하고, <Link>로 부드러운 페이지 전환을 구현하며, 서버 액션으로 프론트엔드와 백엔드의 경계가 허물어집니다.
이 개념들을 이해하고 활용하면 웹 어플리캐이션 설계에 매우 유리해집니다.