사진과 같이 nextjs 블로그 프로젝트를 진행하면서, 카테고리별 포스터를 필터링 하는 기능에 대해 기억하고자 기록해 두려고 작성하게 되었다..😅
⚒️ 사용스택 : nextjs , tailwindcss, typescript
const categories = [...new Set(posts.map(post) => post.category))];
Set 메소드 : 중복을 막아주는 역할로, 특정 속성에 대한 값을 중복 없이 받아올 수 있다.map 메소드 : post 객체 내 category 속성 값만 받아올 수 있다.FilterablePosts 컴포넌트를 생성하여 선택된 카테고리에 맞는 포스트만 렌더링 할 수 있도록 코드를 작성한다.
// 1
"use client";
import { Post } from "@/service/posts";
import { useState } from "react";
import Card from "./Card";
import Categories from "./Categories";
// 2
type Props = {
posts: Post[];
categories: string[];
};
const ALL_POSTS = "All Posts";
export default function FilterablePosts({ posts, categories }: Props) {
const [selected, setSelected] = useState(ALL_POSTS);
// 3
const filtered =
selected === ALL_POSTS
? posts
: posts.filter((post) => post.category === selected);
return (
<section className="flex justify-around">
<ul className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3">
// 4
{filtered.map((post) => (
<li key={post.path}>
<Card post={post} />
</li>
))}
</ul>
<Categories
categories={[ALL_POSTS, ...categories]}
onClick={(selected) => setSelected(selected)}
/>
</section>
);
}
useState로 상태를 관리하기 때문에 클라이언트 컴포넌트로 관리posts, categories에 대한 Props 타입 지정filtered 변수에는 posts 변수에 담겨있는 배열 내 객체들을 map 메소드를 통해 배열 내 객체를 돌며 해당 post의 category의 값이 selected와 동일한 객체만 필터링한다.Categories 컴포넌트를 생성하여 카테고리를 선택할 수 있는 메뉴 컴포넌트를 생성한다.
// 1
type Props = {
categories: string[];
onClick: (category: string) => void;
};
// 2
export default function Categories({ categories, onClick }: Props) {
return (
<section className="flex flex-col items-center">
<h2 className="text-xl font-bold border-b-2 border-blue-400 mb-1">
Category
</h2>
<ul className="flex flex-col items-center">
// 3
{categories.map((category) => (
<li
key={category}
onClick={() => onClick(category)}
className="cursor-pointer hover:text-blue-400"
>
{category}
</li>
))}
</ul>
</section>
);
}
categories, onClick 대한 Props 타입 지정onClick : 카테고리 항목 클릭 이벤트 발생시 매개변수로 받아온 onClick 함수(setSelected)에 해당 category 항목을 전달하여 실행시킨다.