DEV Community

Discussion on: How to Use SWR for Better Data Fetching Approach

Collapse
 
receter profile image
Andreas Riedmüller

Thanks, I did not know about swr/immutable, good to know that this exists.

Regarding the cancellation, did you test what SWR does when you call mutate while the request is still loading? I think it updates with the data from the first call when it is returned first and then gets overridden by the second response of the secong mutate/request right?

Cancelling would also come with issues, if the API response is slower then the frequency of calling mutate it would never show a result.

The only real issue would be if the first mutate gets a response later (after the response originating from the second mutate call) and overrides the data of the second response which was returned faster. But I am quite confident this is handle correctly by SWR. Didn’t find information about this behavior in the docs though.

I did recently use SWR in a Chrome Extension for accessing local storage, also very handy.

You can spread the remaining properties of useSWR in your hook you might be more future proof and it is a little less code, like so:

import useSWR from 'swr/immutable';

const useRandomQuote = () => {
  const { data, ...restSWR } = useSWR(
    'https://api.quotable.io/quotes/random',
    fetcher
  );

  return { ...restSWR, quote: data?.[0] };
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
femincan profile image
Furkan Emin Can • Edited

First of all, thank you so much for taking the time to leave such a detailed and thoughtful comment on my first article.

I'd like to start with your first two questions:

As you mentioned your second question when you call the mutate function before the existing request is completed, the existing request continues while the new request starts concurrently. But, SWR only uses the last request's response to replace the current data. As a result, other requests become unnecessary.

Concurrent Request Example

If you want to check the code in the gif above, I prepared a branch in CodeSandBox: codesandbox.io/p/github/femincan/q...

I apologize, but I couldn't fully grasp the points you made in the canceling section of your comment.

Lastly, thank you for your suggestion. I have updated my code and article based on it.

Collapse
 
receter profile image
Andreas Riedmüller • Edited

Ah ok, so it looks like it is ignoring the old request responses, kind of makes sense.

What I meant with the frequency: If you never would have stopped clicking the "New Quote" button the Quote would never have updated. Even though newer data would have arrived already. I hope this is more understandable.

The good thing about this behavior: it does not look like it is randomly updating the quote after mutate is called multiple times.

This would be not ideal if the API responses are very slow and mutate/update would happen very frequently. Which to be honest is not a very realistic use case.

In this case I would not worry about cancelling the requests, it just makes things more complicated and has no big advantage.

If you want to cut down on requests eg. when typing in a TextBox or to let people hammer that button, you could also use throttle or debounce for the api calls.

For the random quote, disabling the button while fetching is a good solution.

And one thing for your code that just came to my mind: If the code for extracting the quote from data is moved to inside the fetcher logic you have all API related code in one place.

And I would rather use { ...restSWR, quote } than { quote, ...restSWR } because the later always wins over the previous. And as ´quote´ is your own property you would never want that to be overriden by restSWR. (This would only happen if useSWR adds a property called quote though.)

Thread Thread
 
femincan profile image
Furkan Emin Can • Edited

I just updated the article to make the section clearer.

I'm not agree with you that "In this case I would not worry about cancelling the requests, it just makes things more complicated and has no big advantage."

If the user's network connection is slow, It results in a long loading process. If we cancel the unnecessary requests, the last request completes faster. You can check the updated section for more information.

Thanks for your suggestions.
I think, I can move the fetcher function inside the useRandomQuote hook. It seems more appropriate for me.
I will also update the return statement based on your suggestion.

Thread Thread
 
receter profile image
Andreas Riedmüller

You are right, it can make a difference, especially if the responses are quite big. This would be a nice feature for useSWR

I found that there is a RFC for cancellation with useSWR: github.com/vercel/swr/discussions/... and it has a pull request as well but not reviewed/merged yet.

Maybe it arrives soon.

Thread Thread
 
femincan profile image
Furkan Emin Can

I agree that it would be a nice addition to useSWR. I hope the pull request gets reviewed and merged soon.

I appreciate our discussion and your contributions to the topic. If you have any further questions or thoughts, feel free to share them.