在 React Query 中使用 useQuery
发起一个带有防抖功能的请求不是直接支持的,因为 useQuery
通常用于立即执行的数据获取。但是,您可以通过结合使用防抖函数(如 lodash
库中的 debounce
函数)来实现这个功能。这样做的关键是将防抖逻辑应用到触发查询的事件上,而不是直接在 useQuery
上。
下面是一个如何实现带有防抖的请求的例子:
首先,您需要安装 lodash
作为项目的依赖,因为我们将使用它提供的 debounce
函数。
bashnpm install lodash
然后,可以在组件中创建一个防抖函数,并在这个函数内部触发 React Query 的查询。
jsximport 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 回复