如何让 SWR 仅在用户更改日期值时获取数据?

How to make SWR only fetch data when user changes date values?

我正在尝试使用 SWR,虽然它很棒,但它会一遍又一遍地获取数据。

我希望它仅在时间间隔发生变化时再次获取数据。

我一直在尝试使用 mutate 来实现这一点,但看起来这不是正确的方法。引用此 post

import useSWR from 'swr';
import { useState } from 'react';

import { apiRequest } from '../../../util/util';
import { format } from 'date-fns';
import groupBy from 'lodash/groupBy';

const fetchSentiment = async (url) => {
  let sentiments = await apiRequest(url);
  sentiments = sentiments.map((el) => ({
    ...el,
    createdDay: format(new Date(el.created * 1000), 'yyyy-MM-dd'),
  }));
  sentiments = groupBy(sentiments, 'createdDay');
  return sentiments;
};

export default function useAnalytics() {
  let d = new Date();
  d.setMonth(d.getMonth() - 1);

  const [dateRange, setDateRange] = useState([d.getTime(), Date.now()]);
  const [startDate, endDate] = dateRange;
  const [shouldFetch, setShouldFetch] = useState(true);

  const handleChange = (e) => {
    //Clean up this code
    if (e[0] != null && e[1] != null) {
      e[0] = e[0].getTime();
      e[1] = e[1].getTime();
    }
    setDateRange(e);
    setShouldFetch(true);
  };

  const { data: sentimentData, error: sentimentError } = useSWR(
    shouldFetch
      ? `xxx=${startDate}&endTime=${endDate}`
      : null,
    fetchSentiment
  );

  const { data: expressionsData, error: expressionsError } = useSWR(
    shouldFetch
      ? `xxx=${startDate}&endTime=${endDate}`
      : null,
    apiRequest
  );

  if (psychometricError || sentimentError || expressionsError) {
    console.log(psychometricError);
  }

  return {
    sentimentData,
    expressionsData,
    overall,
    handleChange,
    setDateRange,
    // sentimentStatistical,
    startDate,
    endDate,
  };
}

如何减少查询总数,但在选择新时间范围时仍然更新?

我正在考虑使用useEffect来监视dateRange的变化,然后使shouldFetch为真?

如果我理解正确,您只想在 dateRange 值更改时在两个 useSWR 调用中获取新数据。

您可以先将 useSWR 替换为 useSWRImmutable 以禁用 SWR 完成的自动重新验证。然后,您可以在 useSWRImmutable 调用中使用数组作为 key 参数以包含 startDateendDate。每次修改这些变量之一时,这都会强制获取函数 re-run。

这是对您的原始代码的一个小重构,它实现了上述建议,并且还消除了对额外 shouldFetch 状态变量的需要。

import useSWRImmutable from 'swr/immutable';

export default function useAnalytics() {
    const [dateRange, setDateRange] = useState(() => {
        const d = new Date();
        d.setMonth(d.getMonth() - 1);
        return [d.getTime(), Date.now()];
    });
    const [startDate, endDate] = dateRange;

    const handleChange = (e) => {
        if (e[0] != null && e[1] != null) {
            e[0] = e[0].getTime();
            e[1] = e[1].getTime();
        }
        setDateRange(e);
    };

    const { data: sentimentData, error: sentimentError } = useSWRImmutable(
        // Pass an array that includes `startDate` and `endDate`
        [`xxx=${startDate}&endTime=${endDate}`, startDate, endDate],
        fetchSentiment
    );

    const { data: expressionsData, error: expressionsError } = useSWRImmutable(
        // Pass an array that includes `startDate` and `endDate`
        [`xxx=${startDate}&endTime=${endDate}`, startDate, endDate],
        apiRequest
    );

    if (psychometricError || sentimentError || expressionsError) {
        console.log(psychometricError);
    }

    return {
        sentimentData,
        expressionsData,
        overall,
        handleChange,
        setDateRange,
        startDate,
        endDate
    };
}