議論とtypesafeフックでクエリを反応させる


私は最近、外部APIから結果をロードした検索入力でプロジェクトに取り組みました.基本的な問題は単純です:ユーザーが検索テキストを入力します.あなたが前にこれらのいずれかを構築している場合は、それが聞こえるように簡単ではない知っている.どのように、我々は「反応する」の検索が「R」、「RE」、「REA」、「REAC」と「反応」の検索に変わることを確実としませんか?

答えは、入力を停止するには、ユーザーの時間を与えるために、APIへのフェッチの呼び出しを議論している.私は反応質問を使用してこの問題に多くの解決策を探しました、そして、私が捜していた望ましい「討論された質問」結果を成し遂げるために本当に一緒に働くカップル・フックをまとめました.

セットアップ


以下のパッケージは次のパッケージに従っています(あなたが既にプロジェクトのNewishバージョンを使用していると仮定します).
  • react-query
  • axios
  • typescript
  • フック


    フックのファイルを2つ作成します

    使用方法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;
    }
    

    ユーザークエリ。TS


    このファイルは、問い合わせの引数を受け取り、Replyクエリを返すカスタムフックを作成しますuseQuery フック、ラッピングaxios.get() , そして、どれが我々のデータから約束を返すでしょうgetStuff 関数.
    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 我々の負債フックに、そして、我々の反応質問フックに対する討論の結果を通過して、データの変化または地位を取り出すことに応じて.あなたは、反応クエリのdevのツールを有効にすることができます結果のクエリをリアルタイムで実行(かなり甘い!)を参照してください.
    // 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 /> */}
        </>
      );
    };