React Native中如何让React-Query无网络时返回缓存数据?
解决React Native中useStudentData Hook的网络缓存逻辑问题
你的核心需求是网络可用时从API拉取最新数据,网络不可用时复用缓存数据,但原代码存在违反React Hook调用规则的问题(在Hook中间进行条件返回),同时没有充分利用react-query的内置缓存能力。以下是修正后的实现方案:
关键修改点
- 移除原代码中
if(!isConnected)的条件分支,避免破坏Hook的调用顺序规则 - 使用react-query的
enabled选项控制请求触发时机:仅当网络连通时才发起API请求 - 修正原代码中未定义的
studentData变量问题,确保逻辑自洽
修改后的完整代码
import { useQuery, UseQueryResult, useQueryClient } from '@tanstack/react-query'; import { useNetInfo } from '@react-native-community/netinfo'; // 导入你的Student类型、API和key定义 export const useStudentData = ( studentId: Student['id'] ): UseQueryResult<Student, Error> => { const queryClient = useQueryClient(); const { isConnected } = useNetInfo(); // 修正queryKey:使用传入的studentId,避免原代码中studentData未定义的问题 const listQueryKey = studentDataKeys.list({ studentIdEq: studentId }); const detailQueryKey = studentDataKeys.detail(studentId); return useQuery<Student, Error>( detailQueryKey, async () => { const { data: student } = await StudentDataAPI.fetchDataById(studentId); // 修正deserialize的参数:使用API返回的student,而非未定义的studentData return StudentData.deserialize({ ...student, assignments: student.assignments?.filter((assignment) => assignment.submitted) }); }, { staleTime: 1000 * 60 * 60 * 10, // 10小时 stale 时间 retry: 0, // 当网络不可用时,禁用API请求,直接复用缓存 enabled: isConnected, // 初始数据从列表缓存中获取(如果存在) initialData: () => { const previousStudentList = queryClient.getQueryData<Student[]>(listQueryKey); return previousStudentList?.find(item => item.id === studentId); }, initialDataUpdatedAt: queryClient.getQueryState(listQueryKey)?.dataUpdatedAt, onError() { console.log("API拉取学生数据失败"); } } ); };
逻辑说明
- 网络可用时:
enabled: isConnected为true,useQuery会正常发起API请求,获取最新数据后自动更新缓存 - 网络不可用时:
enabled为false,useQuery不会发起API请求,直接返回已有的缓存数据(如果存在);如果是首次调用且无缓存,会返回undefined,你可以根据业务需求添加兜底处理 - 缓存复用:react-query会自动管理缓存的存储和读取,无需手动在条件分支中返回缓存,避免了Hook调用顺序的问题
内容的提问来源于stack exchange,提问作者SJaka
相关产品推荐
相关产品推荐

