쿼리스트링, 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>로 부드러운 페이지 전환을 구현하며, 서버 액션으로 프론트엔드와 백엔드의 경계가 허물어집니다.

이 개념들을 이해하고 활용하면 웹 어플리캐이션 설계에 매우 유리해집니다.

728x90