export default function Page() {
return (
<h1>앱 라우터 공부 3일차 🤓</h1>
);
}
먼저 앱 라우터를 사용하는 프로젝트에서 페이지 이동을 어떻게 하는지 알아보자.
앱 라우터 프로젝트에서는 서버 컴포넌트가 존재하기 때문에,
페이지 이동이나 프리페칭 시 Next 서버는 브라우저에게 Javascript Bundle과 함께 RSC Payload
를 함께 전달한다.
➡️ RSC Payload
는 사전 렌더링에서 서버 컴포넌트 실행 시 생성되는 결과물이라고 지난 게시글에서 언급한 바 있다!
➡️ 이것이 당연한 이유는, Javascript Bundle은 클라이언트 컴포넌트만 포함되어 있기 때문이다!
그래서 서버가 브라우저에 전달한 Javascript Bundle을 브라우저에서 실행한 결과와 RSC Payload
가 합쳐져서 페이지를 교체하는 것이다.
위와 같이 search 페이지로 이동 후, 개발자 도구의 Network 탭을 보면 search 페이지에 대한 RSC Payload
가 잘 불러와진 것을 확인할 수 있다.
또한 Javascript Bundle은 현재 search 페이지가 서버 컴포넌트로만 이루어져 있기 때문에 확인할 수 없는 것!
앱 라우터를 사용하는 프로젝트에서 네비게이팅을 적용하며 꼭 알아야 할 사실이 있다. 바로 router import 과정❗️
페이지 라우터를 사용하는 프로젝트에서는 next/router의 useRouter()를 사용했었다. 하지만 앱 라우터 프로젝트에서는 next/navigation의 useRouter()를 사용해야 한다는 점 ✨
라우터 객체를 만들어주고 해당 라우터로 경로 설정해주면 끝!
프리페칭의 개념을 다시 복기하며 ~
현재 search 페이지에서 이동할 가능성이 있는 index 페이지와 book/1 페이지에 대한 모든 데이터를 미리 불러오는 것을 말한다.
이 때 개발자 도구의 네트워크 탭을 보면, 정적인 페이지인 index 페이지는 JS Bundle 파일과 RSC Payload가 모두 불러와졌지만, 동적인 페이지인 book/1 페이지는 RSC Payload만 불러와진 것을 확인할 수 있다.
"use client";
import { useEffect, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import style from "./serachbar.module.css";
export default function Searchbar() {
const router = useRouter();
const searchParams = useSearchParams(); // 현재 페이지에 전달된 쿼리 스트링을 꺼내오는 역할
const [search, setSearch] = useState("");
const q = searchParams.get("q");
// 쿼리 스트링이 변경되면 그 값을 search에 저장.
useEffect(() => {
setSearch(q || "");
}, [q]);
// 사용자가 input 값을 입력하면 그 값을 search에 저장.
const onChangeSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value);
};
const onSubmit = () => {
// 현재 검색어가 없거나, 쿼리 스트링과 검색어가 같다면 페이지 이동을 방지하는 조건.
if (!search || q === search) return;
router.push(`/search?q=${search}`);
};
const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
// 사용자가 누른 키가 enter라면 onSubmit()를 호출해 검색이 이루어지도록 함.
if (e.key === "Enter") {
onSubmit();
}
};
return (
<div className={style.container}>
<input
value={search}
onChange={onChangeSearch}
onKeyDown={onKeyDown}
/>
<button onClick={onSubmit}>검색</button>
</div>
);
}
먼저 클라이언트 컴포넌트여야 하는 검색 바를 살펴보자.
next/navigation에서 useRouter를 불러와서 사용하는 것은 pass.
그 다음으로는 useSearchParams
라는 훅이 있다. 이 훅은 현재 페이지에 전달된 쿼리 스트링을 꺼내오는 역할을 하며, Line12를 보면 get()이라는 메서드를 통해 쿼리 스트링을 변수 q에 저장하는 것을 확인할 수 있다.
(페이지 라우터 프로젝트에서는 router.query.q
를 통해 쿼리 스트링을 불러왔었음!)
onSubmit() 함수를 보면 다음과 같은 하나의 조건이 추가되어 있다.
if (!search || q === search) return;
이 조건은 현재 검색어(search)가 없거나, 쿼리 스트링(q)과 검색어가 같다면 페이지 이동을 방지하는 조건이다.