찍찍이 #검색 페이지

박기범·2025년 1월 9일
0

다음 맡은 페이지는 검색 페이지이다.
이 페이지에서는 다른 유저를 팔로우 하기 위한 검색 페이지를 의미한다.

검색 필터로 유저명, 목표명 별로 검색을 할 수 있다.

custom hooks를 만들어 검색 내용을 불러오도록 하였으며
검색 필터와 검색 키워드는 useState와 zustand 모두 사용하였음.
그 이유는 의도된 것으로!! 검색 트리거 방식이 검색창에서 enter나 클릭이나 따로 사용자의 이벤트가 들어가야지만 검색이 되게끔 해주도록 하였음.

  • 따라서 전역상태가 변할 때마다 refetch 해주도록 하였고 사용자의 이벤트가 입력이 되기 전 렌더링되는 값들은 로컬 상태로 처리하고 입력이 되면 전역상태에 추가되는 것으로 구현하였음.
  • 이를 통해 불필요한 데이터 Fetch를 방지하고, 검색이 의도된 경우에만 서버 요청이 이루어지도록 했음.

검색 컴포넌트 코드

상태 관리

... 검색 input component

export const SearchInput = () => {
  const [localKeyword, setLocalKeyword] = useState('');
  const [localFilter, setLocalFilter] = useState('유저명');
  const { setSearchKeyword, setSearchFilter } = useSearchStore();

  const handleKeyword = (e: ChangeEvent<HTMLInputElement>) => {
    setLocalKeyword(e.target.value);
  };

  const handleKeyPress = (e: KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      handleClick();
    }
  };

  const handleClick = () => {
    setSearchKeyword(localKeyword);
    setSearchFilter(localFilter);
  };

  return (
    <div className="flex h-48 w-full items-center justify-between rounded-62 bg-white px-16 py-8">
      <div className="flex items-center gap-16">
        <SearchFilterDropdown
          localFilter={localFilter}
          setLocalFilter={setLocalFilter}
        />
        <Input
          className="px-0"
          placeholder={PLACEHOLDERS.SEARCH}
          value={localKeyword}
          onChange={handleKeyword}
          onKeyDown={handleKeyPress}
        />
      </div>
      <FaSearch
        className="size-18 cursor-pointer text-custom-gray-100"
        onClick={handleClick}
      />
    </div>
  );
};

데이터 refetching

... 검색 content component

export const SearchContent = () => {
  const { searchFilter, searchKeyword } = useSearchStore();
  const {
    data: searchData,
    refetch,
    isError,
    error,
  } = useSearchQuery({
    searchField: searchFilter,
    keyword: searchKeyword,
  });

  useEffect(() => {
    if (searchKeyword || searchFilter) {
      refetch();
    }
  }, [searchKeyword, searchFilter, refetch]);

 return ...
};

AxiosError를 감지하고, 서버에서 반환된 에러 메시지를 사용자에게 명확하게 전달하도록 설계하였으며, 서버 응답이 없는 경우에도 일반적인 오류 메시지를 제공하여 사용자와 개발자 모두가 문제를 빠르게 이해하고 대응할 수 있도록 함.
특히, 검색 결과와 관련된 에러는 사용자 경험에 중요한 영향을 미치기 때문에, 이를 별도로 다루어 신뢰성과 안정성을 높이는 데 중점을 두었음.

...

export const getSearch = async (request: SearchRequest) => {
  try {
    const response = await axiosInstance.get(API_ENDPOINTS.SEARCH, {
      params: request,
    });
    return response.data;
  } catch (error) {
    let errorMessage = 'An unknown error occurred.';
    if (error instanceof AxiosError) {
      if (error.response) {
        errorMessage =
          error.response.data?.message || 'An unknown error occurred.';
      }
    }
    throw new Error(errorMessage);
  }
};

추후 위 함수뿐만 아니라 다른 api 함수들도 status에 따라 구체적인 에러 처리를 확실하게 할 예정임.

profile
프론트엔드 개발공부를 하고있습니다.

0개의 댓글

관련 채용 정보