如何在 React-query 中使用惰性查询?
How to use Lazy query with React-query?
我正在为我的 API 调用使用 React-query。我想知道是否有一种方法可以以惰性方式调用查询。
意味着仅当查询参数更改时才调用查询。
这是我目前拥有的;我正在使用带有“useEffect”的 hack,如果 recipeName 更改,则 运行 refetch 函数。
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”函数中调用查询。
我可以创建一个自定义的 useLazyQuery 挂钩来处理这个问题,但我想知道 React-query 是否有本地方法来处理这个问题。
这样做
const { isLoading, data } = useQuery([
'homePageSearchQuery',
{recipeName}],
() => searchRecipeByName(recipeName), {}
);
只要 recipeName 的值发生变化,它就会运行查询。
Preferably, I would like to call the query in the "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
更改之间的硬加载状态,请设置 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 秒不活动后触发一个新请求。
- 如果你想要一个提交表单的按钮,最好“提升状态”:有一个查询所依赖的更全局的状态,以及表单的一些本地状态。一旦用户点击“提交”,您将用户选择保存在更高层的状态中,这将触发查询。我喜欢为此使用 url,并且我有一个完整的 codesandbox example here。在该示例中实际的表单状态是不受控制的,但您也可以为此使用状态或表单库
我正在为我的 API 调用使用 React-query。我想知道是否有一种方法可以以惰性方式调用查询。
意味着仅当查询参数更改时才调用查询。
这是我目前拥有的;我正在使用带有“useEffect”的 hack,如果 recipeName 更改,则 运行 refetch 函数。
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”函数中调用查询。
我可以创建一个自定义的 useLazyQuery 挂钩来处理这个问题,但我想知道 React-query 是否有本地方法来处理这个问题。
这样做
const { isLoading, data } = useQuery([
'homePageSearchQuery',
{recipeName}],
() => searchRecipeByName(recipeName), {}
);
只要 recipeName 的值发生变化,它就会运行查询。
Preferably, I would like to call the query in the "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
更改之间的硬加载状态,请设置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 秒不活动后触发一个新请求。
- 如果你想要一个提交表单的按钮,最好“提升状态”:有一个查询所依赖的更全局的状态,以及表单的一些本地状态。一旦用户点击“提交”,您将用户选择保存在更高层的状态中,这将触发查询。我喜欢为此使用 url,并且我有一个完整的 codesandbox example here。在该示例中实际的表单状态是不受控制的,但您也可以为此使用状态或表单库