image

검색 기능

태그
ReactJavascript
상세설명검색 기능 만들기
작성일자2024.01.07

프론트에서 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>
        </>
      );
    }

    결과