最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React SWR - how to know that updating (mutating) is running? - Stack Overflow

programmeradmin1浏览0评论

Im mostly using SWR to get data, however I have a situation that I need to update data. The problem is, I need an indicator that this request is ongoing, something like isLoading flag. In the docs there's a suggestion to use

const isLoading = !data && !error;

But of course when updating (mutating) the data still exists so this flag is always false. The same with isValidating flag:

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

This flag does NOT change when mutation is ongoing but only when its done and GET request has started.

Question

Is there a way to know if my PUT is loading? Note: I dont want to use any fields in state because it won't be shared just like SWR data is. Maybe Im doing something wrong with my SWR code?

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
  } 

Edit: for any other who reading this and facing the same issue... didnt find any solution for it so switched to react-query. Bye SWR

Im mostly using SWR to get data, however I have a situation that I need to update data. The problem is, I need an indicator that this request is ongoing, something like isLoading flag. In the docs there's a suggestion to use

const isLoading = !data && !error;

But of course when updating (mutating) the data still exists so this flag is always false. The same with isValidating flag:

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

This flag does NOT change when mutation is ongoing but only when its done and GET request has started.

Question

Is there a way to know if my PUT is loading? Note: I dont want to use any fields in state because it won't be shared just like SWR data is. Maybe Im doing something wrong with my SWR code?

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
  } 

Edit: for any other who reading this and facing the same issue... didnt find any solution for it so switched to react-query. Bye SWR

Share Improve this question edited Oct 3, 2022 at 21:31 underfrankenwood asked May 22, 2022 at 20:26 underfrankenwoodunderfrankenwood 8932 gold badges12 silver badges32 bronze badges 5
  • 1 I think you should not use a loading indicator after a mutation, an optimstic update is much better from a UX pov. I think you are doing something wrong, not sure how you are handling fetching and data update, but there's something not good. The second parameter function of mutate should be a function to update the cache while you are passing another fetcher. Then use a post call to perform a refetch ? Try to stick with a simple Query -> mutate -> optimistic update -> revalidate pattern. – Cesare Polonara Commented May 22, 2022 at 20:51
  • 1 @CesarePolonara thanks, I will try that. However I really need this indicator, this is what users of my application are used to. – underfrankenwood Commented May 22, 2022 at 21:38
  • 1 @CesarePolonara consider the next use case: refresh mobile screen with your finger (the down gesture) - you want the screen to show loading indicator while fetching the data again. – chenop Commented Aug 2, 2022 at 20:33
  • @underfrankenwood any conclusions? – chenop Commented Aug 2, 2022 at 20:34
  • @chenop The scroll refresh is a GET query it's not related to the OP's question which regards a PUT mutation... – Cesare Polonara Commented Aug 4, 2022 at 15:00
Add a ment  | 

3 Answers 3

Reset to default 2
const { mutate: update } = useSWRConfig();

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

By using react-toastify npm module to show the user status.

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

Hmm based on that: https://swr.vercel.app/docs/conditional-fetching

It should work that the "is loading" state is when your updater is evaluates to "falsy" value.

REMAINDER! I don't know react swr just looked into docs - to much time at the end of the weekend :D

At least I hope I'll start discussion :D

发布评论

评论列表(0)

  1. 暂无评论