簡體   English   中英

如何在 React-query 中使用惰性查詢?

[英]How to use Lazy query with React-query?

我正在為我的 API 調用使用 React-query。 我想知道是否有辦法以懶惰的方式調用查詢。

意思是僅在查詢參數更改時才調用查詢。

這是我目前擁有的; 我正在使用帶有“useEffect”的hack,如果recipeName發生變化,則運行重新獲取function。

export const searchRecipeByName = async (recipeName: string) => {
  return await api.get(
    `/recipes/complexSearch?apiKey=${process.env.NEXT_PUBLIC_SPOONACULAR_API_KEY}&query=${recipeName}&addRecipeInformation=true&fillIngredients=true`
  );
};
  const [recipeName, setRecipeName] = useState("");

  const { data, refetch } = useQuery(
    "homePageSearchQuery",
    () => searchRecipeByName(recipeName),
    { enabled: false }
  );

// HACK
  useEffect(() => {
    if (!!recipeName) {
      refetch();
    }
  }, [recipeName]);

  const handleOnSearchSubmit = async (recipeSearch: RecipeSearch) => {
    setRecipeName(recipeSearch.search);
  };

最好,我想在“handleOnSearchSubmit”function 中調用查詢。

我可以創建一個自定義的 useLazyQuery 鈎子來處理這個問題,但我想知道 React-query 是否有本地方法來處理這個問題。

像這樣做

const { isLoading, data } = useQuery([
    'homePageSearchQuery',
    {recipeName}],
    () => searchRecipeByName(recipeName), {}
);

只要 recipeName 的值發生變化,它就會運行查詢。

最好,我想在“handleOnSearchSubmit”function 中調用查詢。

這是一種非常必要的思考方式,但 react-query 更具聲明性。 您沒有指定:“當我單擊該按鈕時,我想獲取”,但您只是說:“這些是我需要的輸入”並且 react-query 將在這些輸入更改時重新獲取。

因此,您要做的就是將查詢運行所需的內容放入查詢鍵中,以便 react-query

  • 為每個依賴項分別緩存它
  • 只要依賴項尚未准備好,您就可以禁用它
const [recipeName, setRecipeName] = React.useState('')
const { isLoading, data } = useQuery(
  ['homePageSearchQuery', recipeName],
  () => searchRecipeByName(recipeName),
  {
    enabled: !!recipeName
  }
])

然后,您需要做的就是在handleOnSearchSubmit中調用setRecipeName ,然后 react-query 將進行查詢。

您可能需要考慮的更多事項:

  • 如果您想避免在recipeName更改之間硬加載 state,請設置keepPreviousData: true
  • 每次recipeName更改時,上面的代碼都會運行一個查詢。 如果在單擊按鈕時沒有發生這種情況,但只要用戶在輸入字段中輸入內容時說,您就想消除它。 對於這些情況,請考慮類似useDebounce
const [recipeName, setRecipeName] = React.useState('')
const debouncedRecipeName = useDebounce(recipeName, 1000)
const { isLoading, data } = useQuery(
  ['homePageSearchQuery', debouncedRecipeName],
  () => searchRecipeByName(debouncedRecipeName),
  {
    enabled: !!debouncedRecipeName
  }
])

這將允許您輸入數據並將其顯示在文本字段中,但只會在 1 秒不活動后創建一個新的緩存條目/觸發一個新請求。

  • 如果您想要一個提交表單的按鈕,最好“將 state 向上提升”:擁有查詢所依賴的更全局的 state,以及表單的一些本地 Z9ED39E2EA931586B6A985A6942EF57。 一旦用戶點擊“提交”,您將用戶選擇保存在更高的 state 中,這將觸發查詢。 我喜歡為此使用 url,並且我在這里有一個完整的代碼框示例 在該示例中,實際形式 state 不受控制,但您也可以使用 state 或表單庫

你可以使用這個 Wrapper 鈎子在react-query中使用useLazyQuery

import { useCallback, useState } from 'react';
import {
  QueryFunction,
  QueryKey,
  useQuery,
  UseQueryOptions,
  UseQueryResult,
} from 'react-query';

type UseQueryParams = Parameters<typeof useQuery>;

export default function useLazyQuery<TData, TError>(
  key: UseQueryParams[0],
  fetchFn: QueryFunction<TData, QueryKey>,
  options?: Omit<UseQueryOptions<TData, TError, unknown, QueryKey>, 'queryKey' | 'queryFn'>
): [() => void, UseQueryResult<unknown, unknown>] {
  const [enabled, setEnabled] = useState(false);

  const query = useQuery<TData, TError, unknown, QueryKey>(key, fetchFn, {
    ...(options || {}),
    enabled,
  });

  const trigger = useCallback(() => {
    if (!enabled) {
      setEnabled(true);
    }
  }, [fetchFn, enabled]);

  return [trigger, query];
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM