-
Notifications
You must be signed in to change notification settings - Fork 1.2k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing an equivalent of React Query's useQueries hook #1041
Comments
Thanks for the detailed description! So the solution would be something similar to the impl. of useSWRInfinite, but requests are fired together instead of paginated. Happy to add it if someone comes up with a PR, I think |
I think we could use the global mutate function to cache the each item based on its key. import { mutate } from 'swr'
function useSWRList(queryList) {
const mutations = queryList.map(({ queryKey, queryFn }) => {
return mutate(queryKey, () => queryFn(...queryKey))
})
return useSWR(
queryList.map((v) => v.queryKey),
() => Promise.all(mutations)
)
} |
We'd also want to catch errors for each key individually, so that some calls can fire even if others aren't ready. If the first request's key throws an error, the others should still fire. |
@nandorojo Hi, would you mind check the codesandbox again. I have updated the example. const mutations = queryList.map(({ queryKey, queryFn }) => () =>
mutate(queryKey, () => queryFn(...queryKey))
// The data has been saved in cache based on key
.then((v) => v)
// The error has been save in cache base on key
// so the error was handled individually
.catch((e) => ({
error: e,
key: queryKey
}))
) I feel like this pattern might be batter then useQueries hook. It only rerenders onces when all data resolves. |
@promer94 Hi, thanks for the solution. It seems resolving the case. Just to keep in consideration for the PR, in my case I didn't need to So in my case I modified the function like this import useSWR, { mutate, cache } from 'swr'
export function useSWRList(queryList, queryFn) {
const mutations = queryList.map((queryKey) => () => {
const cachedResult = cache.get(queryKey)
if (cachedResult) {
return cachedResult
}
return (
mutate(queryKey, () => queryFn(queryKey))
// The error has been save in cache base on key
// so the error was handled individually
.catch((e) => ({
error: e,
key: queryKey,
}))
)
})
return useSWR(
queryList,
() => Promise.all(mutations.map((v) => v()))
)
} |
Would love to see this! This is useful for any situation where you have lists that contain elements that may be shared across parents. For example imagine looking up portfolios of stocks (eg. an array of tickers). There's a chance for overlap between two portfolios (eg. they both contain AAPL), so you want to cache the individual stock queries. This type of use case can't be replicated with sub-components and the normal |
Is this currently being worked on? We could use this & would be interested in picking this up. |
I'm looking for this feature too!! |
Hi @promer94 thanks for the response and the examples above. However, like many above we would love to have the ability to load data from multiple requests as data comes back, in order words, rerender anytime we receive a response from one of the requests. To respond to your reply above:
We have optimized UX to handle layout and component caching for performance. Showing some data as soon as they're available has been proven to help with attracting users' attention and retention. I feel like dealing with layout and rerender performance should be something developers can take into consideration themselves. We would love to have |
Any status update on this? |
I started working on it initially before getting pulled away to other things. I also realize, based on convos here, that the desired semantics of this hook aren't necessarily clear. I'll probably just pick an approach to get it into a PR for discussion, but I don't really have so much code written that, should someone else have the time, they wouldn't/shouldn't pick this up. |
Agreed here @mAAdhaTTah, I think the most important thing to do first is getting a RFC/proposal instead of jumping into the implementation directly. |
I think the project should aim to mimic the interface that Having the dependency collection optimization in mind, I would suggest the const { data, error, isValidating } = useSWRList(["a", "b", "c"], config);
// data[i]
// error[i]
// isValidating[i] rather than an array of objects: const results = useSWRList(["a", "b"], config);
// results[i].data
// results[i].error
// results[i].isValidating because when fetching each item on the list, chances are that all of the given items will be used – the access of However, Also, I think the
I would recommend suggesting developers to use the |
@shuding and anyone else in this issue: I've opened an RFC for this hook. I'm also willing to implement it once we agree on the intended semantics. I was doing some refactoring of our code and need this hook to fix some things so I finished up the RFC I started a while back. Also happy to implement this once we align on semantics. Let me know what y'all think! |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
There does not seem to be an equivalent of the React Query's useQueries hook in SWR.
Being able to run a variable number of queries in parallel using SWR and yet benefit from caching per individual items would be a big enabler. I know that I can use a custom fetcher with SWR which returns the Promise.all of multiple requests, but that doesn't cache results individually.
A good use case is given on the link above. Imagine having to fetch multiple users at once, and then in other parts of the code, only request for one of these users. You would definitely like to avoid making a new request for the same user requested earlier.
Note: I tried to ask the community for a way to do that with SWR, without success.
The text was updated successfully, but these errors were encountered: