Initial fallback for request with dynamic urls
See original GitHub issueBug 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:
- Created 2 years ago
- Reactions:8
- Comments:16 (7 by maintainers)
Hi! For
useSWRInfinite
, you need to useAnd then
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.
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
:It’s not documented, but we will once it gets finalized.