question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Initial fallback for request with dynamic urls

See original GitHub issue

Bug report

Description / Observed Behavior

I have functionality in the app which includes list with loading during scrolling + list filters.I am using useSWRInfinite with fallbackData option. The problem is that setting fallbackData makes data property from useSWRInfinite always set and in result between filter changes I see old data from fallback and no loading. It’s replacing the list for a moment with original fallback list.

The problem is also that fallback option suggested in docs is object literal, where swr allows keys others than string, these keys are stringified by internal functions of swr (serialize). So in result where I have complicated server query with many params I am not able to replicate the key in form of string because swr doesn’t do simple JSON.stringify by uses internal serialize function.

Both those problems create no possibility to use prefetched data. The hack needs to be applied which checks if we have first call of useSWRInifinite. But this also do not solve all isssues as the page in the end is not in cache.

Here is example with standard useSWR https://codesandbox.io/s/useswr-fallback-behaviour-d9c8i

So yes I understand why it works like that - fallback is related with given key, so new key means fallback is applied. Problem is that I have one fallback for initial request, initial filters and this fallback does not apply to any other next filter. I understand why we cannot say it is fallback for initial request as useSWR doesn’t see difference between one call and another outside of key.

I wanted to use fallback property but my key is serialised internally by swr and function for this is internal part of the lib. So I am stuck with that also. What I need to do is hack like this one:

https://codesandbox.io/s/useswr-fallback-behaviour-hacked-wrongly-6vbcf?file=/src/App.js But this does not work as useEffect is called right after and we really have state change and “loading” instead of prefetched data. To deal with it we need some kind of counter like:

https://codesandbox.io/s/useswr-fallback-behaviour-hacked-counter-clve0?file=/src/App.js Take a look now it does work as expected (almost) as there is one rendering with fallback when we firstly change the key (its a small second but even though kind of not wanted behaviour).

Finally the problem does not allow me to easily use useSWR with prefetched data. I cannot:

  • use fallback because it accepts only strings as keys, where I have array
  • I cannot define that fallbackData is only for first request in some group/category of keys

Why do you use array, use string as a key

I could do that, but the current fetcher works with array of query params and makes a call from it. Also this fetcher is not only used in one place, in result it means that such a change has a big impact:

  • we need to make proper url as a key in nextjs level
  • we need to change fetcher to accept url string not a list of arguments which makes different responsibilities of this function

This is problematic as most fetcher utilities allow on using them with separated url and separated query params. Current fallback forces manually query params concatenation.

And the last is - why useSWR accepts as a key any other thing than string if fallback doesn’t support this. It looks like something is missed in the design.

Expected Behaviour

Possibility to use Map instead of object literals in fallback in order to not needing to serialize manually the key. This would allow to pass arrays in the same way we can do that as key in useSWR.

Maybe some way to define fallback for category or requests. A way to tag/categorize some group of keys, For example I would like to say useSWR(key, {category: 'users_list', fallbackForCategory: fallbackData} then fallback would be applied only for first request of this category.

Repro Steps / Code Example

The example issue ( fallback shows for every key change): CodeSandbox - issue example

Example hack: CodeSandbox - hack example

Additional Context

SWR 1.0.1

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:8
  • Comments:16 (7 by maintainers)

github_iconTop GitHub Comments

14reactions
shudingcommented, Oct 4, 2021

Hi! For useSWRInfinite, you need to use

import { unstable_serialize } from 'swr/infinite'

And then

fallback: {
  [unstable_serialize(getKey)]: [initialPageData]
}

Sending undefined is not possible as this is not JSON serializeble

If undefined is in the key array, it should be possible (please let me know if it doesn’t) because we’re not using standard JSON serialization.

2reactions
shudingcommented, Oct 1, 2021

Hi, thanks for writing the description carefully! This is definitely something we need to refine in the future. However, currently you can use this to serialize array/object keys and then use it as the key of fallback:

import { unstable_serialize, SWRConfig } from 'swr'

<SWRConfig value={{ fallback: {
  [unstable_serialize(['array', 'key'])]: 'fallback_data'
}}}

It’s not documented, but we will once it gets finalized.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Manually constructing a Dynamic Link URL - Firebase
You can create a Dynamic Link by manually constructing a URL with the following form: ... &apn= package_name [&amv= minimum_version ][&afl= fallback_link ] ......
Read more >
Script static fallback content for Angular $http request
I'd like to include fallback code that displays two static HTML elements in place of the remote content if the GET request fails....
Read more >
Data Fetching: getStaticPaths - Next.js
If fallback is 'blocking' , new paths not returned by getStaticPaths will wait for the HTML to be generated, identical to SSR (hence...
Read more >
Redirecting and Remapping with mod_rewrite
It describes how you can use mod_rewrite to redirect and remap request. ... If it exists, we take that name, else we rewrite...
Read more >
How to set a fallback URL in Progressier
Fallback URLs allow you to define alternative URLs for failed network requests. If the request to a URL fails for whatever reason (e.g....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found