-
검색하는 페이지에서 서버 부담을 줄이기 위해 디바운싱을 적용시켜 검색기능 리팩토링을 진행하였다.
훅으로 만들어 빼두기
import { useState, useEffect } from "react"; const useDebounce = (value: string, delay: number = 500) => { const [debounced, setDebounced] = useState(value); useEffect(() => { const handler = setTimeout(() => setDebounced(value), delay); return () => clearTimeout(handler); }, [value, delay]); return debounced; }; export default useDebounce;
훅 불러와서 useDebounce 적용하기
import React, { useState } from "react"; import { getRoomsWithKeyword } from "@/utils/supabase/roomAPI"; import SearchIcon from "@/assets/images/icon_search.svg"; import S from "@/style/mainpage/main.module.css"; import Image from "next/image"; import { toast } from "react-toastify"; import useGetRoomsSocket from "@/hooks/useGetRoomsSocket"; import useDebounce from "@/hooks/useSearchDebounce"; const RoomSearch = () => { const { setRooms } = useGetRoomsSocket(); const [search, setSearch] = useState<string>(""); const debouncedValue = useDebounce(search); //NOTE - 방 목록 검색 const searchHandler = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); if (!search.trim()) return; try { const rooms = await getRoomsWithKeyword(debouncedValue); setRooms(rooms); } catch (error) { toast.error("검색 중 오류가 발생했습니다."); } }; return ( <form onSubmit={searchHandler}> <div className={S.roomSearch}> <label htmlFor="search">검색하기</label> <input type="text" id="search" value={search} onChange={(e) => setSearch(e.target.value)} placeholder="방 이름을 입력해 주세요." /> <button> <Image src={SearchIcon} alt="search Icon" /> </button> </div> </form> ); }; export default RoomSearch;
사용방법은 매우 간단하게 적용했다
커스텀 훅으로 빼둔 useDebounce를 input value내용을 handler에 넘겨서
마지막 요청에 값을 업데이트해서 수파베이스에 있는 데이터 내용을 불러온다.
그리고 debouncedValue값이 업데이트 될 때 실행되도록 개선해 두었다.
리팩토링
"use client"; import React, { useEffect, useState } from "react"; import { getRoomsWithKeyword, getRooms } from "@/utils/supabase/roomAPI"; import SearchIcon from "@/assets/images/icon_search.svg"; import S from "@/style/mainpage/main.module.css"; import Image from "next/image"; import { toast } from "react-toastify"; import useGetRoomsSocket from "@/hooks/useGetRoomsSocket"; import useDebounce from "@/hooks/useSearchDebounce"; import { FormSearchProps } from "@/types"; const FormSearch = ({ placeholder }: FormSearchProps) => { const { setRooms } = useGetRoomsSocket(); const [search, setSearch] = useState<string>(""); const debouncedValue = useDebounce(search, 500); //NOTE - 메인페이지 방 목록 검색 const searchHandler = (e: React.ChangeEvent<HTMLInputElement>) => { setSearch(e.target.value); }; useEffect(() => { const fetchRooms = async () => { try { if (!debouncedValue.trim()) { const allRooms = await getRooms(0, 20); setRooms(allRooms); return; } const roomKeyword = await getRoomsWithKeyword(debouncedValue); setRooms(roomKeyword); } catch (error) { toast.error("검색 중 오류가 발생했습니다."); } }; fetchRooms(); }, [debouncedValue]); return ( <> <div className={S.roomSearch}> <label htmlFor="search">검색하기</label> <input type="text" id="search" value={search} onChange={searchHandler} placeholder={placeholder} /> <button type="button"> <Image src={SearchIcon} alt="search Icon" /> </button> </div> </> ); }; export default FormSearch;
0.5초마다 검색하게 만들었고, 사용자가 검색 내용을 비웠을때 다시 전체데이터를 불러오는 방식으로 리팩토링을 진행하였다.
개념정리는 다음 포스팅에!
Debounce와 Throttleing 개념(디바운싱&쓰로틀링)
IceCraft - search검색부분(리팩토링), 디바운싱 적용하기검색하는 페이지에서 서버 부담을 줄이기 위해 디바운싱을 적용시켜 검색기능 리팩토링을 진행하였다.훅으로 만들어 빼두기import { useState, u
seokachu.tistory.com
'✨ 기억보다 기록을 > 프로젝트' 카테고리의 다른 글
IceCraft - EmailJS 적용하기 (0) 2024.06.30 IceCraft - 팝업 만들기 (쿠키 라이브러리) (0) 2024.06.30 IceCraft - skeleton라이브러리 추가하기 (0) 2024.06.21 IceCraft - 메인페이지swiper 슬라이드 추가하기 (0) 2024.06.20 IceCraft - 마피아 게임페이지 조건에 따른 모달창 리팩토링 (0) 2024.06.20 댓글