FrontEnd/React

[React] 검색 기능 구현

jh2ee 2023. 7. 23. 15:04

구현할 기능은 검색 기능이다.

레이아웃

요청 받은 디자인은 다음과 같다.

처음엔 div안에 돋보기 이미지와 input 태그를 사용하는 방법으로 구현했으나 검색 시 뷰의 전환과 동시에 쿼리를 넘겨야 했기에 form 태그를 이용하는 방법을 택했다.

카멜 케이스로 작성해야하는데 스네이크 케이스가 너무 보기 편하다..

<form className="search-container" onSubmit={submit} >
    <img className="search-icon" src={Icon} alt="search icon" />
    <input
        className="search-input"
        type="text"
        placeholder="나의 어려움은 무엇인가요?" 
    />
</form>

기능 구현

검색 대상은 게시물의 제목과 내용이다.

쿼리 전달

useState를 이용해 입력된 query를 받아오고 변화를 감지하기 위해 onChange를 사용했다.

filter함수를 통해 입력값과 데이터를 소문자로 변환해 전달할 수 있도록 했다.

const [query, setQuery] = useState("");
const keys = ["title", "content"]; // 키를 사용해 효율적으로 검색
const onChange = (e) => {
    setQuery(e.target.value.toLowerCase());
}
const search = (data) => {
    return data.filter((item) =>
        keys.some((key) => item[key].toLowerCase().includes(query))
    );
};

페이지 전환( 뷰 전환 )

검색 시 뷰 전환을 위해 useNavigate를 엔터키 입력을 처리하기 위해 이벤트를 추가했다.

const navigate = useNavigate();
const submit = (e) => {
    e.preventDefault();
    // 검색 결과 시 이동할 url
    navigate(`/search?query=${encodeURIComponent(query)}`);
    console.log(query);
}

코드 전문

뷰에 데이터 넘기는 과정은 진행 중에 있다.

import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";

import "./SearchBar.css"
import Icon from "../Image/Search.png";

function SearchBar(){
    const [query, setQuery] = useState("");
    const keys = ["title", "content"];
    const onChange = (e) => {
        setQuery(e.target.value.toLowerCase());
    }
    const search = (data) => {
        return data.filter((item) =>
            keys.some((key) => item[key].toLowerCase().includes(query))
        );
    };

    const navigate = useNavigate();
    const submit = (e) => {
        e.preventDefault();
        // 검색 결과 시 이동할 url (임시로 지정)
        navigate(`/search?query=${encodeURIComponent(query)}`);
        console.log(query);
    }
    
    return(
        <form className="search-container" onSubmit={submit} >
            <img className="search-icon" src={Icon} alt="search icon" />
            <input
                className="search-input"
                type="text" 
                value={query}
                onChange={onChange}
                placeholder="나의 어려움은 무엇인가요?" 
            />
        </form>
    )
}

export default SearchBar;