React SWR - 如何知道更新(变异)正在运行?

11

我主要使用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。


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

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",
  });

0
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",
    };
};

你的回答可以通过添加更多支持信息来改进。请[编辑]以添加进一步细节,例如引用或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

-3
根据这个链接: https://swr.vercel.app/docs/conditional-fetching 应该是当你的updater的值为“假”时,“正在加载”的状态才能起作用。
剩下的!我不熟悉React SWR,只是查看了文档——周末结束时花费了太多时间:D
至少我希望我能开始讨论:D

我不明白“条件获取”在这里如何帮助我,但还是谢谢你的回答:D - underfrankenwood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接