프론트에서 filter() 함수를 통해 검색 기능을 만들 수 있어 개인 블로그에도 검색 기능을 넣었다.
검색어
먼저 input 태그의 input의 value값은 event.target.value으로 useState에 value값을 넣어 주며 입력 시 데이터를 필터 할 함수( handleSearchInputChange() ) 에 event.target.value을 넘긴다.
React에서 input 관리 관련 글
const [search, setSearch] = useState<string>("");
//
<input
value={search}
onChange={(e) => handleSearchInputChange(e.target.value)}
placeholder="Search"
className="bg-primary"
/>
검색어에 따른 데이터 필터
- useEffect를 통해 filteredList에 전체 데이터를 넣어주어 미 검색 시에는 전체 데이터를 보여준다.
- 검색을 시작하면 호출되는 함수인 handleSearchInputChange() 에서 검색 조건에 일치하는 데이터만 필터하여 filteredList 에 업데이트 한다.
- 데이터를 보여주는 영역에서는 전체 데이터( blogs.results )가 아닌 초기 데이터 또는 필터 된 데이터를 를 가지고 있는 filteredList 를 map()함수를 통해 보여준다.
⭐ toLowerCase() 사용 이유
대소문자를 구분하지 않고 검색하도록 만들어 사용자가 검색어를 입력할 때 대소문자를 신경 쓰지 않고 검색할 수 있게 하기 위해서 사용한다. toLowerCase()를 사용하면 입력된 검색어와 비교 대상 문자열을 모두 소문자로 만들어 비교하므로 이러한 문제를 방지할 수 있다.
const [filteredList, setFilteredList] = useState<ListResults[]>([]);
useEffect(() => {
setFilteredList(blogs.results);
}, [blogs.results]);
const handleSearchInputChange = (searchWord: string) => {
setSearch(searchWord);
let updatedList = blogs.results;
updatedList = blogs.results.filter((item: ListResults) => {
return (
item?.properties["이름"].title[0].plain_text
?.toLowerCase()
.includes(searchWord) ||
item?.properties.Description?.rich_text[0].plain_text
?.toLowerCase()
.includes(searchWord)
);
});
setFilteredList(updatedList);
};
//
<div>
{filteredList.map((item: ListResults) => (
<Post
key={item.id}
item={item}
/>
))
)}
</div>
전체 코드
import Post from "@/components/post";
import { useEffect, useState } from "react";
import { BlogistObject, ListResults } from "@/InterfaceGather";
export default function Blog({ blogs }: BlogistObject) {
const [search, setSearch] = useState<string>("");
const [filteredList, setFilteredList] = useState<ListResults[]>([]);
useEffect(() => {
setFilteredList(blogs.results);
}, [blogs.results]);
const handleSearchInputChange = (searchWord: string) => {
setSearch(searchWord);
let updatedList = blogs.results;
updatedList = blogs.results.filter((item: ListResults) => {
return (
item?.properties["이름"].title[0].plain_text
?.toLowerCase()
.includes(searchWord) ||
item?.properties.Description?.rich_text[0].plain_text
?.toLowerCase()
.includes(searchWord)
);
});
setFilteredList(updatedList);
};
return (
<>
<div className="laptop-max-width">
<div className="post-content-area">
<div className="post-search-container">
<input
value={search}
onChange={(e) => handleSearchInputChange(e.target.value)}
placeholder="Search"
className="bg-primary"
/>
</div>
<div>
{filteredList.map((item: ListResults) => (
<Post
key={item.id}
item={item}
/>
))
)}
</div>
<MoveToTop />
</div>
</div>
</>
);
}
결과
'React' 카테고리의 다른 글
눈 내리는 효과 (0) | 2024.08.28 |
---|---|
Pagination (0) | 2024.08.26 |
react-joyride (0) | 2024.08.26 |
React 에서 탭 기능 구현 (0) | 2024.08.26 |
LocalStorage 값 저장, 가져오기, 삭제 (0) | 2024.08.26 |