React Query实现地址选择后带缓存的命令式GET请求最佳实践
最优方案:用TanStack Query的
queryClient.fetchQuery 这是最贴合你需求的方案,理由很直接:
- 自带永久缓存:设置
staleTime: Infinity就能让地址详情数据永远存在缓存里,不用自己写useState维护缓存; - 自动处理请求风险:内部会自动取消组件卸载后还在运行的请求,不用手动写清理逻辑;
- 保证
onSelect只触发一次:不管是读缓存还是发新请求,拿到数据后直接调用onSelect,逻辑清晰,不会漏触发也不会重复触发; - 代码简洁易读:比手动管理缓存少写一堆冗余代码,后续维护成本低。
具体实现代码
import { useQueryClient } from '@tanstack/react-query'; const AddressSelector = ({ onSelect }) => { const queryClient = useQueryClient(); const handleAddressSelect = async (selectedAddress) => { // 用地址唯一标识(比如ID)作为查询键,确保缓存的唯一性 const queryKey = ['addressDetails', selectedAddress.id]; // fetchQuery会先查缓存,没有就发请求,拿到数据后直接用 const addressDetails = await queryClient.fetchQuery({ queryKey, queryFn: () => fetch(`/api/addresses/${selectedAddress.id}/details`).then(res => res.json()), staleTime: Infinity, // 永久缓存,不会重新请求 }); // 拿到详情后立刻通知父组件,确保只调用一次 onSelect(addressDetails); }; return ( <div> {/* 这里是你的地址联想搜索下拉列表 */} <DropdownMenu onSelect={handleAddressSelect}> {/* 联想结果项 */} </DropdownMenu> </div> ); };
为啥不选另外两个方案?
- 手动
await retrieve():得自己写缓存逻辑(比如用useState存一个缓存对象),还要手动处理组件卸载时的请求取消,容易漏写导致内存泄漏,代码冗余; useQuery的onSuccess:onSuccess只有在新请求完成的时候才会触发,如果数据已经在缓存里,这个回调不会执行,你得额外处理缓存命中的情况,要么加判断要么强制refetch(),反而把逻辑搞复杂了。
内容的提问来源于stack exchange,提问作者rony l
相关产品推荐
相关产品推荐

