【问题标题】:React SWR - how to know that updating (mutating) is running?React SWR - 如何知道更新(变异)正在运行?
【发布时间】:2022-12-18 14:50:26
【问题描述】:

我主要使用 SWR 来获取数据,但是我有一种情况需要更新数据。问题是,我需要一个表明此请求正在进行的指示器,例如 isLoading 标志。在文档中有使用的建议

const isLoading = !data && !error;

但是当然,当更新(变异)data 仍然存在,所以这个标志总是 false。与 isValidating 标志相同:

const { isValidating } = useSWR(...);

当变异正在进行时,这个标志不会改变,但只有当它完成并且GET请求已经开始时才会改变。

问题

有没有办法知道我的PUT 是否正在加载?笔记:我不想使用状态中的任何字段,因为它不会像 SWR 数据那样共享。也许我的 SWR 代码有问题?

const fetcher = (url, payload) => axios.post(url, payload).then((res) => res); 
  // ^^^^^ its POST but it only fetches data

const updater = (url, payload) => axios.put(url, payload).then((res) => res);
  // ^^^^^ this one UPDATES the data

const useHook = () => {
  const { data, error, mutate, isValidating } = useSWR([getURL, payload], fetcher);

  const { mutate: update } = useSWRConfig();

  const updateData = () => {
    update(getURL, updater(putURL, payload)); // update data
    mutate(); // refetch data after update
  };

  return { 
    data,
    updateData,
    isValidating,               // true only when fetching data
    isLoading: !data && !error, // true only when fetching data
  } 

编辑:对于阅读本文并面临相同问题的任何其他人...没有找到任何解决方案,因此切换到react-query。再见SWR

【问题讨论】:

  • 我认为你不应该在突变后使用加载指示器,从 UX pov 进行乐观更新要好得多。我认为你做错了什么,不确定你是如何处理获取和数据更新的,但有些地方不好。第二个参数函数变异应该是在传递另一个获取器时更新缓存的函数。然后使用后调用来执行重新获取?尝试坚持使用简单的查询 -> 变异 -> 乐观更新 -> 重新验证模式。
  • @CesarePolonara 谢谢,我会试试的。但是我真的需要这个指标,这是我的应用程序的用户习惯的。
  • @CesarePolonara 考虑下一个用例:用手指刷新移动屏幕(向下手势)——您希望屏幕在再次获取数据时显示加载指示器。
  • @underfrankenwood 有什么结论吗?
  • @chenop 滚动刷新是一个 GET 查询,它与 OP 的关于 PUT 突变的问题无关......

标签: javascript reactjs swr


【解决方案1】:
const { mutate: update } = useSWRConfig();

  const updateData = () => {
    // this will return promise
    update(getURL, updater(putURL, payload)); // update data
    mutate(); // refetch data after update
  };

通过react-toastify npm 模块显示用户状态。

// first wrap your app with: import { ToastContainer } from "react-toastify";

 import { toast } from "react-toastify";

 const promise=update(getURL, updater(putURL, payload))

 await toast.promise(promise, {
    pending: "Mutating data",
    success: "muttation is successfull",
    error: "Mutation failed",
  });

【讨论】:

    【解决方案2】:
    const markSourceMiddleware = (useSWRNext) => (key, fetcher, config) => {
        const nextFetcher = (...params) =>
            fetcher(...params).then((response) => ({
                source: "query",
                response,
            }));
    
        const swr = useSWRNext(key, nextFetcher, config);
        return swr;
    };
    
    const useHook = () => {
        const {
            data: { source, response },
            mutate,
        } = useSWR(key, fetcher, { use: [markSourceMiddleware] });
    
        const update = mutate(
            updateRequest().then((res) => ({
                source: "update",
                response,
            })),
            {
                optimisticData: {
                    source: "update",
                    response,
                },
            }
        );
    
        return {
            update,
            updating: source === "update",
        };
    };
    

    【讨论】:

      【解决方案3】:

      嗯,基于此: https://swr.vercel.app/docs/conditional-fetching

      当您的 updater 评估为“虚假”值时,“正在加载”状态应该起作用。

      余!我不知道 react swr 只是查看了文档 - 在周末结束时花了很多时间 :D

      至少我希望我会开始讨论 :D

      【讨论】:

      • 我不明白“条件获取”如何在这里帮助我,但感谢您的回答:D
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-27
      • 2021-11-02
      相关资源
      最近更新 更多