#reactjs #next.js #swr
Вопрос:
У меня возникли проблемы с крючком useSWR, который либо слишком часто выбирался из-за срабатывания в нескольких местах на монтировании, либо из-за сбоя, потому что он не был запущен на монтировании в первый раз.
Моя идея состояла в том, чтобы просто проверить кэш внутри сборщика, чтобы увидеть, есть ли там уже значение в интервале обновления, и отправить его обратно, которое, похоже, работает, но я не уверен на 100%, будет ли оно работать так, как я намереваюсь, после того, как mutate будет вызван извне… Есть ли что-то, что я упускаю из виду, почему я не должен использовать этот метод?
В принципе, mutate(url) станет таким же, как mutate(url, false), если он был вызван в интервале обновления, что, я полагаю, нормально, но в идеале я бы хотел, чтобы он работал как обычно.
const getTimestampKey = (key: string) => key "--ts";
const hasExpired = (key: string) => {
const timestampKey = getTimestampKey(key);
if (!cache.has(timestampKey)) return true;
let prevTime = cache.get(timestampKey);
return Date.now() > prevTime RefreshInterval;
};
const saveTimestamp = (key: string) => {
const timestampKey = getTimestampKey(key);
cache.set(timestampKey, Date.now());
};
export const getApplicationsByAssociationKey = (selectedAssociationId: string) => {
return `${applicationsUrl}?associationId=${selectedAssociationId}`;
};
export const getUserApplicationsFetcher = (url: string) => {
if (!url) throw new Error("Bad argument exception.");
if (!hasExpired(url)) {
let cachedData = cache.get(url);
if (cachedData) return cachedData;
}
return bffClient
.get<ApplicationsResponseArray>(url, { withCredentials: true })
.then((res) => {
saveTimestamp(url); // save the timestamp
return res.data;
});
};
export const useGetUserApplicationsByAssociationId = (selectedAssociationId: string) => {
const { data, error, mutate, isValidating } = useSWR<ApplicationsResponseArray, any>(
selectedAssociationId ? getApplicationsByAssociationKey(selectedAssociationId) : null,
getUserApplicationsFetcher,
{
refreshInterval: RefreshInterval
}
);
return {
data: (data || []) as Application[],
error: error,
loading: !data amp;amp; !error,
mutate: mutate
};
};
Варианты, которые я пробовал, — это оба:
refreshInterval: refreshInterval, revalidateOnMount: ложь, revalidateOnFocus: ложь, revalidateOnReconnect: ложь, обновление при запуске: ложь, обновление при закрытии: ложь
или разрешить повторную проверку, но повторить попытку по ошибке, но ни одно из решений, похоже, не работает так, как планировалось, то есть использовать кэшированные данные, если они находятся в интервале обновления.