페이지 이동과 데이터 주고받기: 라우팅과 폼 처리
폴더 기반의 직관적인 라우팅 방식과, 사용자로부터 입력(Form)을 받아 서버로 전달하는 기초를 학습합니다.
우리가 만드는 서비스는 보통 하나의 화면으로 끝나지 않습니다. 메인 화면에서 상세 화면으로 넘어가거나, 로그인 정보를 입력하고 가입을 완료하는 등 페이지 간의 이동과 데이터 전송이 끝없이 일어납니다. 이번 시간에는 Next.js의 가장 강력한 기능 중 하나인 '폴더 기반 라우팅'과, 사용자의 입력을 서버로 안전하게 전달하는 '폼(Form)' 처리 방법에 대해 살펴봅니다.
폴더가 곧 페이지가 되는 App 라우팅
웹 브라우저의 주소창에 특정 주소(URL)를 입력했을 때 그에 맞는 화면을 보여주는 시스템을 라우팅(Routing) 이라고 부릅니다. Next.js 13 버전부터 도입된 App Router는 이 라우팅 방식을 믿을 수 없을 만큼 직관적으로 만들었습니다.
직관적인 파일 기반 라우팅
전통적인 방식에서는 특정 주소에 어떤 화면을 띄울지 복잡한 설정 파일을 따로 작성해야 했습니다. 하지만 Next.js에서는 단순히 프로젝트 폴더를 만드는 것만으로 주소가 생성됩니다.
`app` 폴더 내부에 새로운 폴더를 만들고, 그 안에 `page.tsx`라는 이름의 파일을 생성하면 즉시 화면에 접속할 수 있는 라우팅이 완성됩니다.
Next.js App 폴더와 URL 라우팅 규칙
- app/page.tsx
- 기본 메인 주소 (예: www.example.com/)
- app/about/page.tsx
- 어바웃 주소 (예: www.example.com/about)
- app/store/shoes/page.tsx
- 하위 폴더 중첩 라우팅 (예: www.example.com/store/shoes)
동적 라우팅 (Dynamic Routing)
만약 쇼핑몰에 수백 개의 상품이 있다면, 폴더를 수백 개 만들어야 할까요? 그럴 때는 폴더 이름을 대괄호 `[ ]`로 감싸서 동적 라우팅을 구현합니다.
예를 들어 폴더 이름을 `app/products/[id]/page.tsx`로 만들면, 사용자가 `/products/1`로 접속하든 `/products/99`로 접속하든 모두 이 하나의 페이지 컴포넌트가 응답하게 됩니다. 이때 `[id]` 부분의 값(1이나 99)은 해당 페이지 안에서 변수처럼 읽어와 사용할 수 있습니다.
페이지 간 자연스러운 이동
Next.js에서 페이지를 이동할 때는 전통적인 HTML의 `<a>` 태그 대신 Next.js가 제공하는 전용 도구를 사용해야 속도와 성능을 최대로 끌어올릴 수 있습니다.
Link 컴포넌트의 활용
일반적으로 화면의 메뉴나 텍스트를 클릭해서 다른 페이지로 넘어갈 때는 Next.js의 `Link` 컴포넌트를 사용합니다. 이 컴포넌트는 사용자가 클릭하기도 전에 다음 화면에 필요한 데이터를 미리 백그라운드에서 가져오는(Prefetching) 영리한 기능을 내장하고 있습니다. 덕분에 클릭하는 순간 화면이 번쩍이는 로딩 없이 마치 스마트폰 앱처럼 부드럽고 즉각적으로 화면이 전환됩니다.
프로그래밍 방식의 이동 (useRouter)
버튼 클릭 후 결제가 완료되면 자동으로 완료 페이지로 넘어가야 하는 상황처럼, 코드 로직의 결과에 따라 화면을 이동시켜야 할 때가 있습니다. 이때는 클라이언트 컴포넌트에서 `useRouter`라는 훅(Hook)을 불러와서 사용합니다. 이 기능을 이용하면 `router.push('/success')` 같은 명령어를 통해 우리가 원하는 특정 시점에 강제로 사용자를 이동시킬 수 있습니다.
사용자의 입력을 서버로: 폼(Form) 처리
라우팅을 통해 페이지를 만들었다면, 이제 그 페이지에서 사용자로부터 이메일이나 비밀번호, 댓글 등을 입력받아 서버로 전송해야 합니다.
React에서의 기본 폼 처리
HTML의 전통적인 `<form>` 태그는 폼을 제출하는 순간 화면 전체를 강제로 새로고침해 버리는 단점이 있습니다. 그래서 React와 Next.js 개발에서는 보통 이 새로고침을 막고(이벤트 기본 동작 방지), 사용자가 입력한 값을 State에 실시간으로 저장해 두었다가 전송 버튼을 누를 때 자바스크립트를 이용해 데이터를 서버로 쏘아 올리는 방식을 사용해 왔습니다.
Server Actions를 활용한 현대적인 데이터 전송
하지만 최근 Next.js 생태계에서는 복잡한 State나 새로고침 방지 코드를 일일이 작성할 필요가 없는 Server Actions라는 획기적인 방식이 도입되었습니다.
서버 액션(Server Action)을 활용한 데이터 전송
클라이언트에서 복잡한 처리 과정을 거치지 않고, 폼이 제출될 때 직접 서버에서 실행될 함수를 지정해줄 수 있습니다.
// 서버에서 실행될 데이터 저장 함수
async function savePost(formData: FormData) {
'use server'
const title = formData.get('title');
// 여기서 데이터베이스에 즉시 저장합니다!
}
// 클라이언트 화면 컴포넌트
export default function PostPage() {
return (
<form action={savePost}>
<input type="text" name="title" />
<button type="submit">글 작성하기</button>
</form>
)
}이 방식을 사용하면 코드가 훨씬 짧아질 뿐만 아니라, 자바스크립트가 브라우저에서 제대로 작동하지 않는 예외적인 오류 상황에서도 사용자의 폼 제출이 안전하게 서버로 전달된다는 강력한 장점이 있습니다. AI에게 폼 코드를 요청할 때 "Server Actions 방식을 적용해서 폼을 만들어주세요"라고 지시하면 훨씬 모던하고 간결한 코드를 얻을 수 있습니다.
개념 퀴즈
퀴즈 답을 맞춰야 학습 완료가 됩니다.Next.js App Router 구조에서 사용자가 접속하는 'www.mysite.com/profile' 경로의 화면을 만들려면 파일 이름을 어떻게 지정해야 할까요?
3줄 요약
- 1Next.js App Router는 폴더 구조가 그대로 웹 주소 경로가 되는 직관적인 라우팅을 제공합니다.
- 2화면 이동 시에는 속도 향상을 위해 <a> 태그 대신 Next.js의 Link 컴포넌트를 사용합니다.
- 3최신 Next.js에서는 복잡한 상태 관리 대신 Server Actions를 활용해 사용자 폼 입력을 서버로 간결하게 전달합니다.