对于input的值 我们设置一个state 来保存,但是不代表input的值一更改就执行相应的函数,比如fetchData,我们肯定是希望用户值输入完成之后,在执行fetch,不然用户100ms一变,不能100ms执行依次fetch。
scss
//这里是input的onChange
const [searchValue, setSearchValue] = useState("");
// 只有300ms后用户不在操作了 才会去更新debounse的值
const debouncedSearchValue = useDebounce(searchValue, 300);
//这里你可以当成 使用axios fetchData
const { data: collections, loading: collectionsAreLoading } =
useCollectionSearch(debouncedSearchValue);
不过不同的是 他这里是使用的Apollo client来获取数据的,所以debouncedSearchValue不变,Apollo client不会去发送一个新的请求的。 如果使用的查询方式没有这种控制的话,这种方式可能并不合适 或者 你需要自己使用useEffect来使用debouncedSearchValue做依赖 去执行fetchData apollo 默认是 cache-first 参数不变 不会向服务器重新查询的 直接拿缓存的数据 useDebounse
scss
export default function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
// Update debounced value after delay
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
// Cancel the timeout if value changes (also on delay change or unmount)
// This is how we prevent debounced value from updating if value is changed ...
// .. within the delay period. Timeout gets cleared and restarted.
return () => {
clearTimeout(handler)
}
}, [value, delay])
return debouncedValue
}
apollo 的查询 在uniswap 文件自己看可以了 但是我看他的graphql 中有个thegraphql 这里的相关的types和hook是generated的, 不知道是用什么弄的 之后会查一下
这里拿chatgpt 生成了两个例子 一个是 axios 一个是react query这个与apollo一样可以设置查询依赖
用 Axios 重写
若要使用 Axios 替换 Apollo Client,你需要手动管理请求的发起,并利用 React 的 useEffect
钩子来侦听 debouncedSearchValue
的变化:
scss
javascriptCopy code
import axios from 'axios';
import { useState, useEffect } from 'react';
function useCollectionSearchWithAxios(query: string) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (query) {
setLoading(true);
axios.get(`/api/search_collections`, { params: { query } })
.then(response => {
setData(response.data); // 假设 API 直接返回所需格式
})
.catch(error => {
console.error("Failed to fetch data:", error);
setData([]);
})
.finally(() => {
setLoading(false);
});
}
}, [query]); // 侦听 query 变化
return { data, loading };
}
使用 React Query 重写
React Query 提供了类似于 Apollo Client 的功能,但用于任何异步数据源,包括 REST API。与 Apollo 类似,React Query 也管理缓存和数据更新:
javascript
javascriptCopy code
import { useQuery } from 'react-query';
import axios from 'axios';
function fetchCollections(query) {
return axios.get(`/api/search_collections`, { params: { query } })
.then(res => res.data);
}
function useCollectionSearchWithReactQuery(query) {
const { data, isLoading, isError } = useQuery(['collections', query], () => fetchCollections(query), {
enabled: !!query // 只有当 query 非空时才执行查询
});
return {
data: data || [],
loading: isLoading,
error: isError
};
}
在这里,useQuery
的第一个参数是查询的键(在这种情况下是一个数组,包括固定的 'collections'
和变量 query
),这有助于 React Query 识别和管理缓存。enabled
选项用于控制是否执行查询,我们将其设为只有当 query
非空时为真,类似于前面例子中的 skip
逻辑。
总结
每种方法都有其适用场景:
- Apollo Client 最适合 GraphQL 数据获取。
- Axios 配合
useEffect
是一个通用的解决方案,适用于任何 REST API 调用。 - React Query 提供了类似 Apollo 的数据同步和缓存机制,适用于更广泛的数据获取需求,包括 REST API。