일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- ES6+
- next.js
- DOM
- 햇소
- es6
- JavaScript
- object
- AI
- react
- hatso
- dev
- 최적화
- ES5+
- API
- hooks
- 함수
- CSS
- developerlife
- array
- git
- 변수
- JS
- gitCLI
- github
- learn next.js
- 선택자
- 우아한테코톡
- Python
- This
- html5
Archives
- Today
- Total
codinghatso
Learn Next.js 제 11장 : Adding Search and Pagination 본문
-ai를 사용해 개념정리 했음을 공지합니다.-
invoices page를 완성하는 챕터입니다. invocies page에는 검색기능과 6개의 고객 정보를 담는 테이블 6개를 넘어서면 다음 page의 데이터를 가져오는 Pagination 기능 총 3가지를 구현합니다.
검색 원리 분석
- /dashboard/invoices?page=1&query=pending URL쿼리를 객체로 묶어 보면 이렇게 표시할 수 있다.
- {page: '1', query: 'pending'}.
'use client';
import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
import { useSearchParams, usePathname, useRouter } from 'next/navigation';
import { useDebouncedCallback } from 'use-debounce';
export default function Search({ placeholder }: { placeholder: string }) {
const searchParams = useSearchParams();
const pathname = usePathname();
const { replace } = useRouter();
const handleSearch = useDebouncedCallback((term) => {
const params = new URLSearchParams(searchParams);
params.set('page', '1');
if (term) {
params.set('query', term);
} else {
params.delete('query');
}
replace(`${pathname}?${params.toString()}`);
}, 300);
return (
<div className="relative flex flex-1 flex-shrink-0">
......
</div>
);
}
📌 변수 분석
- searchParams = useSearchParams();
- 현재 URL의 쿼리 파라미터(검색 매개변수) 를 가져오는 훅.
- searchParams.get("page") → ?page=2 값을 가져올 수 있음.
- 주로 필터, 페이지네이션 등에 사용됨.
- pathname = usePathname();
- 현재 URL의 경로(path)만 반환하는 훅.
- 예: https://example.com/dashboard?page=2 → /dashboard 반환.
- 쿼리 파라미터를 제외한 URL 경로를 알고 싶을 때 사용됨.
- replace = useRouter();
- Next.js의 라우터 객체를 가져오는 훅.
- replace(url) → 현재 URL을 새 URL로 교체(뒤로 가기 불가).
- 페이지네이션, 필터 변경 시 페이지를 새로고침 없이 갱신할 때 사용됨.
🚀 즉, 이 세 변수는 URL 경로와 쿼리 파라미터를 조작하여 검색, 필터, 페이지네이션을 구현하는 데 사용됨! 😊
전체적인 흐름은 아래와 같습니다.
- 사용자의 입력한 값을 코드로 받아와 활용한다.
- function handleSearch(term: string) { ... } 핸들러
- onChange={(e) => { handleSearch(e.target.value); }} input 이벤트 감지
- searchParams로 URL을 업데이트합니다.
- import { useSearchParams } from 'next/navigation'; 라이브러리 사용
- const searchParams = useSearchParams(); 라이브러리 변수 선언
- function handleSearch(term: string) { const params = new URLSearchParams(searchParams); } 헨들러에서 사용가능하게 선언
- if (term) { params.set('query', term); } else { params.delete('query'); } 핸들러에서 쿼리 판별 후 set | delete 사용
- const pathname = usePathname(); usePathname에서 pathname 변수 선언
- const { replace } = useRouter(); useRouter에서 replace 변수 선언
- replace(`${pathname}?${params.toString()}`); replace를 이용해서 URL 업데이트
- 위 코드아래 변수 설명 참조
- URL을 입력 필드와 동기화(sync) 상태로 유지합니다.
- defaultValue={searchParams.get('query')?.toString()} defaultValue로 URL을 채움 즉 동기화
- 검색 쿼리를 반영하도록 테이블을 업데이트합니다.
최종코드
///app/dashboard/invoices/page.tsx
import Pagination from '@/app/ui/invoices/pagination';
import Search from '@/app/ui/search';
import Table from '@/app/ui/invoices/table';
import { CreateInvoice } from '@/app/ui/invoices/buttons';
import { lusitana } from '@/app/ui/fonts';
import { InvoicesTableSkeleton } from '@/app/ui/skeletons';
import { Suspense } from 'react';
import { fetchInvoicesPages } from '@/app/lib/data';
export default async function Page(props: {
searchParams?: Promise<{
query?: string;
page?: string;
}>;
}) {
const searchParams = await props.searchParams;
const query = searchParams?.query || '';
const currentPage = Number(searchParams?.page) || 1;
const totalPages = await fetchInvoicesPages(query);
return (
<div className="w-full">
......
</div>
);
}
여기서 짚고 넘어갈 부분은 props로 받아오는 query의 타입을 정의한다는 것이다.
export default async function Page(props: {
searchParams?: Promise<{
query?: string;
page?: string;
}>;
}){...}
'WEB > Next.js' 카테고리의 다른 글
Learn Next.js 제 13장 : Handling Errors (0) | 2025.03.12 |
---|---|
Learn Next.js 제 12장 : Mutating Data (0) | 2025.03.12 |
Learn Next.js 제 10장 : Partial Prerendering (0) | 2025.03.11 |
Learn Next.js 제 9장 : Streaming (0) | 2025.03.10 |
Learn Next.js 제 8장 : Static and Dynamic Rendering (0) | 2024.02.20 |
Comments