Debounced 및 Typesafe React Query with Hooks

저는 최근에 외부 API에서 결과를 로드하는 검색 입력이 있는 프로젝트에서 작업했습니다. 기본 문제는 간단합니다. 사용자가 검색 텍스트를 입력하면 구성 요소가 결과 목록을 표시합니다. 하지만 이전에 이 중 하나를 구축했다면 그것이 말처럼 쉽지 않다는 것을 알 것입니다. "React"에 대한 검색이 "R", "Re", "Rea", "Reac"및 "React"에 대한 검색으로도 바뀌지 않도록 하려면 어떻게 해야 합니까?



대답은 API에 대한 가져오기 호출을 디바운싱하여 사용자에게 입력을 중지할 시간을 주는 것입니다. 나는 React Query를 사용하여 이 문제에 대한 많은 솔루션을 찾았고, 내가 찾고 있던 원하는 "디바운스된 쿼리"결과를 달성하기 위해 함께 잘 작동하는 몇 가지 후크를 함께 모았습니다.

설정



따라하려면 다음 패키지가 필요합니다(프로젝트에서 이미 새로운 버전의 React를 사용하고 있다고 가정).
  • react-query
  • axios
  • typescript

  • 후크



    후크용 파일 2개를 만듭니다.

    useDebounce.ts



    이 파일은 상태 업데이트 시 시간 초과 지연을 설정하는 사용자 정의 후크를 생성합니다(이 경우 사용자 입력 대기). 시간 초과가 존재하면 시간 초과도 지워집니다.

    import React from "react";
    
    export default function useDebounce(value: string, delay: number = 500) {
      const [debouncedValue, setDebouncedValue] = React.useState(value);
    
      React.useEffect(() => {
        const handler: NodeJS.Timeout = setTimeout(() => {
          setDebouncedValue(value);
        }, delay);
    
        // Cancel the timeout if value changes (also on delay change or unmount)
        return () => {
          clearTimeout(handler);
        };
      }, [value, delay]);
    
      return debouncedValue;
    }
    


    useReactQuery.ts



    이 파일은 쿼리 인수를 수락하고 React QueryuseQuery 후크를 반환하고 axios.get() 를 래핑하여 getStuff 함수의 데이터로 Promise를 반환하는 사용자 정의 후크를 생성합니다.

    import { useQuery } from "react-query";
    import axios from "axios";
    
    export type QueryResponse = {
      [key: string]: string
    };
    
    const getStuff = async (
      key: string,
      searchQuery: string,
      page: number
    ): Promise<QueryResponse> => {
      const { data } = await axios.get(
        `https://fetchurl.com?query=${query}&page=${page}`
      );
    
      return data;
    };
    
    export default function useReactQuery(searchQuery: string, page: number) {
      return useQuery<QueryResponse, Error>(["query", searchQuery, page], getStuff, {
        enabled: searchQuery, // If we have searchQuery, then enable the query on render
      });
    }
    


    소비



    컨테이너.tsx



    기본적으로 그게 다야! 이제 우리가 해야 할 일은 컨테이너 구성 요소로 이동하여 후크를 작동시키는 것입니다! searchQuery를 디바운스 후크에 전달하고 디바운스 결과를 React 쿼리 후크에 전달하고 데이터 변경 또는 가져오기 상태에 응답합니다. React Query 개발 도구를 활성화하고 결과 쿼리가 실시간으로 실행되는 것을 볼 수 있습니다(매우 훌륭합니다!).

    // import { ReactQueryDevtools } from "react-query-devtools";
    import useDebounce from "../../hooks/useDebounce";
    import useReactQuery from "../../hooks/useReactQuery";
    
    export type ContainerProps = {
      searchQuery: string;
      isFetchingCallback: (key: boolean) => void;
    };
    
    export const Container = ({
      searchQuery,
      isFetchingCallback,
    }: Readonly<ContainerProps>): JSX.Element => {
      const debouncedSearchQuery = useDebounce(searchQuery, 600);
      const { status, data, error, isFetching } = useReactQuery(
        debouncedSearchQuery,
        page
      );
    
      React.useEffect(() => isFetchingCallback(isFetching), [
        isFetching,
        isFetchingCallback,
      ]);
    
      return (
        <>
          {data}
          {/* <ReactQueryDevtools /> */}
        </>
      );
    };
    

    좋은 웹페이지 즐겨찾기