redux 如何使用本地存储的RTK查询结果?

l3zydbqr  于 2022-12-23  发布在  其他
关注(0)|答案(1)|浏览(172)

我用createApiFn创建了一个API端点。我需要在localStorage中存储响应数据一段时间,然后从LS中获取它,而不是发出请求。当计时器超时时,用useQuery更新数据。

export const geoApi = createApi({
    reducerPath: 'geoApi',
    baseQuery: fetchBaseQuery({ baseUrl: GEO_URL }),
    endpoints: (builder) => ({
        getData: builder.query<any, void>({
            query: () => 'geo-data',
        }),
    }),
});

export const { useGetDataQuery } = geoApi;

我可以让它在组件内逻辑(伪代码):

let geoData = null;
const cachedData = ls.get('GEO_DATA');

if (cachedData && dataIsUpToDate()) {
  geoData = cachedData;
} else {
  const res = useGetDataQuery();

  geoData = res.data;
  updateCachedData(geoData);
}

但我想在redux存储逻辑中进行。

mutmk8jj

mutmk8jj1#

一段时间后,我建议使用钩子(修改它为您的情况):

function useCachedData(key, ttl = Infinity, query) {
    const [trigger] = query();
    const [data, updateData] = useState();

    const refreshCache = async () => {
        const fetched = await trigger();

        localStorage.setItem(key, JSON.stringify({ at: Date.now(), data: fetched.data });

        updateData(fetched.data);
    }

    useEffect(() => {
        const cached = localStorage.getItem(key);
        let isValid = false;
        if (cached) {
            const { at, data } = JSON.parse(cached);

            if (at + ttl > Date.now()) {
                isValid = true;
                updateData(data);
            }
        }

        if (!isCached) {
            refreshCache();
        }
    }, []);

    return data;
}

以及惰性查询的用法:

// ...component logic
const geoData = useCachedData('GEO_DATA', 60 * 1000, () => useLazyQuery());

相关问题