Next.js는 페이지 이동 시 공통 레이아웃을 유지하면서 성능을 최적화한다. 하지만 이러한 최적화 과정에서 쿼리 파라미터나 경로 정보를 올바르게 관리하는 것이 중요하다.
// app/teams/page.tsx
export default function TeamsPage({
searchParams,
}: {
searchParams: { filter: string; sort: string }
}) {
return (
<div>
<h1>팀 목록</h1>
<p>필터: {searchParams.filter}</p>
<p>정렬: {searchParams.sort}</p>
</div>
);
}
// components/TeamFilter.tsx
'use client';
import { useSearchParams } from 'next/navigation';
export default function TeamFilter() {
const searchParams = useSearchParams();
const filter = searchParams.get('filter');
return (
<div>
<h2>현재 필터</h2>
<div className="filter-status">
{filter === 'active' ? '활성 팀만 보기' : '모든 팀 보기'}
</div>
</div>
);
}
// app/products/[category]/page.tsx
export default function CategoryPage({
params,
}: {
params: { category: string }
}) {
return (
<div>
<h1>{params.category} 카테고리</h1>
<ProductList category={params.category} />
</div>
);
}
// components/Navigation.tsx
'use client';
import { usePathname } from 'next/navigation';
export default function Navigation() {
const pathname = usePathname();
return (
<nav>
<Link
href="/"
className={pathname === '/' ? 'active' : ''}
>
홈
</Link>
<Link
href="/products"
className={pathname.startsWith('/products') ? 'active' : ''}
>
제품
</Link>
</nav>
);
}
// app/products/page.tsx
import { ProductFilter } from '@/components/ProductFilter';
import { ProductSort } from '@/components/ProductSort';
import { ProductList } from '@/components/ProductList';
export default function ProductsPage({
searchParams,
}: {
searchParams: {
category?: string;
sort?: string;
page?: string;
}
}) {
return (
<div className="products-page">
<div className="filters">
<ProductFilter />
<ProductSort />
</div>
<ProductList
category={searchParams.category}
sort={searchParams.sort}
page={searchParams.page}
/>
</div>
);
}
// components/ProductFilter.tsx
'use client';
import { useSearchParams, useRouter } from 'next/navigation';
export default function ProductFilter() {
const router = useRouter();
const searchParams = useSearchParams();
const updateFilter = (category: string) => {
const params = new URLSearchParams(searchParams.toString());
params.set('category', category);
router.push(`/products?${params.toString()}`);
};
return (
<div className="filter-controls">
<button onClick={() => updateFilter('electronics')}>
전자기기
</button>
<button onClick={() => updateFilter('clothing')}>
의류
</button>
</div>
);
}
// ❌ 잘못된 사용
// app/layout.tsx
export default function Layout({ children }) {
// 레이아웃에서 직접 쿼리 파라미터 접근 불가
const searchParams = useSearchParams(); // 에러 발생!
return <div>{children}</div>;
}
// ✅ 올바른 사용
// 필요한 정보를 자식 컴포넌트로 전달
export default function Layout({ children }) {
return (
<div>
{children}
</div>
);
}