乐闻世界logo
搜索文章和话题

React Query 中 useQuery 如何发起防抖请求?

5 个月前提问
4 个月前修改
浏览次数84

1个答案

1

在 React Query 中使用 useQuery 发起一个带有防抖功能的请求不是直接支持的,因为 useQuery 通常用于立即执行的数据获取。但是,您可以通过结合使用防抖函数(如 lodash 库中的 debounce 函数)来实现这个功能。这样做的关键是将防抖逻辑应用到触发查询的事件上,而不是直接在 useQuery 上。

下面是一个如何实现带有防抖的请求的例子:

首先,您需要安装 lodash 作为项目的依赖,因为我们将使用它提供的 debounce 函数。

bash
npm install lodash

然后,可以在组件中创建一个防抖函数,并在这个函数内部触发 React Query 的查询。

jsx
import React, { useState } from 'react'; import { useQuery } from 'react-query'; import { debounce } from 'lodash'; const fetchData = async (searchText) => { const response = await fetch('/api/data?search=' + encodeURIComponent(searchText)); if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }; function SearchComponent() { // 设置一个状态来存储搜索文本 const [searchText, setSearchText] = useState(''); // 使用 react-query 的 `useQuery`,但不直接触发请求 // 我们传入一个独特的查询键,并在查询函数中使用当前的 searchText 状态 // 这样,只有 searchText 改变时才会执行请求 const { data, error, isLoading } = useQuery( ['search', searchText], () => fetchData(searchText), { // 如果 searchText 为空字符串,则不执行查询 enabled: searchText.trim() !== '' } ); // 创建一个防抖函数来更新 searchText 状态 // 这个防抖函数将在用户停止打字后一段时间才会执行 const debouncedSetSearchText = debounce(setSearchText, 300); // 这是一个处理输入框变化的函数 // 它将被防抖,所以不会对每个按键都更新状态和执行请求 const handleSearchChange = (event) => { const value = event.target.value; debouncedSetSearchText(value); }; return ( <div> <input type="text" placeholder="Search..." onChange={handleSearchChange} /> {isLoading ? ( <div>Loading...</div> ) : error ? ( <div>Error: {error.message}</div> ) : ( <div> {/* 渲染数据 */} </div> )} </div> ); }

在以上代码中,handleSearchChange 函数将会在用户输入时被调用,并通过防抖函数 debouncedSetSearchText 来更新 searchText 状态。因为我们在 useQuery 的配置中将 enabled 选项设置为仅在 searchText 非空时才为 true,这样就只会在防抖函数执行后且 searchText 有值时触发数据请求。

这样,即使用户在输入框中快速输入,也不会发送大量的请求,只有在用户停止输入一段指定的时间(本例中为 300ms)之后,才会根据最新的搜索词发起请求,从而实现了防抖效果。

2024年6月29日 12:07 回复

你的答案