Just Do IT!

[React] 재사용 가능한 검색창 UI component 만들기 본문

개발 공부/React

[React] 재사용 가능한 검색창 UI component 만들기

MOON달 2024. 10. 20. 14:13
728x90
반응형

이번에 dodream 프로젝트를 하면서, 검색창이 여러 페이지에 쓰인다는 걸 깨달았다.

그래서 이번에는 나름대로 중복되는 코드를 줄이고 조금 더 효율적으로 프로젝트를 하고자

component 폴더 안에 UI 폴더를 만들었고, 그 안에 여러 페이지에서 쓰이는 UI component들을 생성했다.

 

그 중 하나가 검색창 컴포넌트이다.

 

import React from "react";
import { FaSearch } from "react-icons/fa";

const SearchInput = ({ value, onChange, placeholder, onSearch }) => {
  const handleKeyDown = (e) => {
    if (e.key === "Enter") {
      onSearch();
    }
  };

  return (
    <div className="relative w-full">
      <input
        type="text"
        value={value}
        onChange={onChange}
        onKeyDown={handleKeyDown} // 엔터 키 이벤트 처리
        placeholder={placeholder}
        className="border border-gray-300 rounded-md p-2 pr-10 w-full focus:outline-none focus:ring-2 focus:ring-blue-500 placeholder:text-sm"
      />
      <button
        onClick={onSearch} // 검색 버튼 클릭 시 검색 수행
        className="absolute right-2 top-1/2 transform -translate-y-1/2 p-1"
      >
        <FaSearch className="text-gray-500" />
      </button>
    </div>
  );
};

export default SearchInput;

 

tailwind를 사용했기에 className이 조금 길지만 이건 스타일 코드라 함께 적었다.

엔터 키를 치면 검색이 되도록 엔터 키 이벤트 역시 추가했다.

react-icon을 사용해서 검색 아이콘까지 넣었다.

 

 

 

활용 예시

이제 내가 프로젝트에 적용했단 코드를 적어보자면,

 

import React, { useState } from "react";
import SearchInput from "../ui/SearchInput";

const TotalSearch = () => {
  const [keyword, setKeyword] = useState("");

  const handleSearchKeyword = (e) => {
    setKeyword(e.target.value);
  };

  return (
    <div>
      <SearchInput
        value={keyword}
        onChange={handleSearchKeyword}
        placeholder="검색어를 입력하세요"
      />
    </div>
  );
};

export default TotalSearch;

 

메인 페이지에서 전체 문제집, 스터디를 검색할 검색 창이다.

keyword로 검색할 거라 useState를 통해 상태 관리를 해주었고 onchange 이벤트도 추가했다.

 

Input component에 placeholder도 추가해주었기 때문에 placeholder에 적힐 문구도 함께 적어두었다.

 

 

 

그러면 이렇게 검색창 컴포넌트가 나온다.

아직 백엔드 api와 연동하지는 않았지만 나름대로 재사용 가능한 컴포넌트를 만들었다는 점에 블로그에 적어둔다.ㅋㅋㅋ

728x90