SWR 似乎在同一个缓存键下缓存了两个不同的请求。我该如何解决?

SWR seems to cache two different requests under same cache key. How do I fix this?

我像这样使用 Axios 作为 SWR 的获取器:

// axios.js
import axios from 'axios';

// Create axios instance.
const axiosInstance = axios.create({
    baseURL: process.env.API_URL,
    withCredentials: true,
    xsrfCookieName: 'csrftoken',
    xsrfHeaderName: 'X-CSRFToken',
});

export default axiosInstance;

const fetcher = (url) => axiosInstance.get(url).then((res) => res.data);
const optionsFetcher = (url) => axiosInstance.options(url).then((res) => res.data);
export { fetcher, optionsFetcher };

然后我像这样获取数据:

// withProblem.js
import useSWR from 'swr';
import { fetcher, optionsFetcher } from './axios';

const withProblemOptions = (id) => {
    // eslint-disable-next-line react-hooks/rules-of-hooks
    const { data, error, mutate } = useSWR(`/api/sources/issues/${id}`, optionsFetcher);
    console.log('REceived optons', data);

    return {
        options: data?.actions?.PUT,
        isOptionsLoading: !error && !data,
        isError: error,
        mutate,
    };
};

const withProblem = (id, options) => {
    // eslint-disable-next-line react-hooks/rules-of-hooks
    const { data, error, mutate } = useSWR(`/api/sources/issues/${id}`, fetcher, options);
    console.log('Received problem', data);

    return {
        problem: data,
        isProblemLoading: !error && !data,
        isError: error,
        mutate,
    };
};

export { withProblemOptions, withProblem };

在我的组件中,我有以下代码:

    const { problem, isProblemLoading, mutate } = withProblem(id, {
        onSuccess: (data) => {
            setProblemState(data);
        },
    });
    const { options, isOptionsLoading } = withProblemOptions(id);

现在我在控制台中看到的内容(由 withProblem.js 中的代码记录):

Received problem Object { id: 2958,  … } withProblem.js:20:12
REceived options Object { id: 2958,  … } withProblem.js:7:12
Received problem Object { id: 2958,  … } withProblem.js:20:12
REceived options Object { id: 2958,  … } withProblem.js:7:12

看起来因为两个获取函数共享完全相同的 URL 响应被缓存在完全相同的键下,无论使用的请求方法是否不同。因为当我在组件中切换 withProblem 和 withProblemOptions 的顺序时,我遇到了完全相同的问题,但数据是我从 OPTIONS 请求中获得的数据,而不是像以前那样从 GET 请求中获得的数据

那么我该如何解决这个问题呢?我是否需要创建自己的缓存提供程序,它使用请求方法作为缓存键的一部分?

您可以针对每种情况使用不同的组合键,例如:

const { data, error, mutate } = useSWR({url: `/api/sources/issues/${id}`, method: 'options'}, fetcher, options);

const { data, error, mutate } = useSWR({url: `/api/sources/issues/${id}`, method: 'get'}, fetcher, options);


// And the fetcher would look like that
const fetcher = ({url, method}) => axiosInstance[method](url).then((res) => res.data);

// Alternatively you an pass key as array, not object, but it's a bit less clear in my opinion 
const { data, error, mutate } = useSWR([`/api/sources/issues/${id}`, 'get'], fetcher, options);