rtk-incubator / rtk-query

Data fetching and caching addon for Redux Toolkit
https://redux-toolkit.js.org/rtk-query/overview
MIT License
626 stars 31 forks source link

Is selectFromResult not usable when paginating, sorting and/or filtering a collection? #229

Closed nielskrijger closed 3 years ago

nielskrijger commented 3 years ago

Let me start with the disclaimer that I'm new to Redux Toolkit and RTK-Query :-) Sorry if this question was already addressed or something is planned related to this. I understand it's in alpha.


I was looking through the RTK Query examples and am considering it for a personal project.

I do admit I was a bit puzzled about the usefulness of the selectFromResult-helper. To me it seems to be only viable in a very narrow set of circumstances (one that I don't encounter usually in a real-life).

Let's assume a master/detail page setup like this:

example.com/posts?query=test&page=3&sort=time-descending
example.com/posts/123

The RTK Query shows the following example:

const { post } = api.useGetPostsQuery(undefined, {
    selectFromResult: ({ data }) => ({ post: data?.find((post) => post.id === id) }),
});

This assumes (I think) it is feasable to fetch all posts on a detail page. That might be OK for a personal weblog but not much else I reasoned.

In effect, usually I'd like to look through all GET /posts?...-requests that have been made thus far regardless of any query param that was sent with the request. Is such a use case covered in RTK Query? Or will it in the future?

Given the same RTK example a more logical fallback request if selectFromResult fails to yield a result is to invoke the single GET /post/123-request:

const { post } = api.useGetPostQuery('123');

(as opposed to fetching a collection).

The simplest way around it seems to me to hook into the redux actions triggered by RTK Query (postsApi/executeQuery/fulfilled) and store the posts-data in redux yourself in a separate slice.

Then in the detail page fetch it using a selector from redux, with a fallback on GET /posts/123.

Am I missing something?

It feels a bit like I'd be goinging against the idea of having RTK Toolkit maintain a cache of the requests. Since now I'm sortof inclined to make my whole app depend on that custom slice (controlled by the app / me, rather than RTK) for consistency's sake (one source of truth). Or is that the recommended approach?

((a huge advantage compared to Apollo GQL is it seems much more trival to debug and work my way around these issues since RTK Query just used redux!))

phryneas commented 3 years ago

selectFromResult is an edge case usage, most often used to work on existing data while preventing re-renders of the component if the underlying query refetches and delivers new data, but does not change the data used by this component.

This might for example be useful when displaying a list, but having each list child access the data from cache, maybe because there are multiple nested components in-between and you have React.memoed a component further up the tree to slow down rerenders.

Or maybe you are using query data, but don't care for isFetching, which would turn false -> true -> false (each time rerendering the component) when another component with the same query triggers a rerender.

So you selectFromResult but strip out isFetching. (caveat: this exact example is still fiddly, but will be better in the next release)

nielskrijger commented 3 years ago

Thanks for the clarification @phryneas

It's purpose finally "clicked" after reading your explanation. I was trying to abuse it for the wrong purpose.

I'll close the ticket.