0

I am using react-query in my project and it works great

I wonder if react-query has a selector feature. I use react-query to fetch a list of posts, for example, and would like to filter only the completed post. I want to cache the filter result so the next time I filter the list again, it can return the cache. Basically, the feature I want is the same as selectors in recoil

4 Answers 4

2

react-query added first-class support for selectors with its release of version 3.

Here's example usage from the library:

it('should be able to select a part of the data with select', async () => {
    const key = queryKey()
    const states: UseQueryResult<string>[] = []

    function Page() {
      const state = useQuery(key, () => ({ name: 'test' }), {
        select: data => data.name,
      })
      states.push(state)
      return null
    }

    renderWithClient(queryClient, <Page />)

    await sleep(10)

    expect(states.length).toBe(2)
    expect(states[0]).toMatchObject({ data: undefined })
    expect(states[1]).toMatchObject({ data: 'test' })
  })
Sign up to request clarification or add additional context in comments.

Comments

0

It's important to have in mind that react-query does not provide a local state. All fetched data is a temporary representation (cache) of the server state. It implements the SWR (stale-while-revalidate) pattern.

Although you can achieve what you want by selecting the data from the cache provided by react-query(you need to do it yourself, there are no selectors) it might be tricky if you use pagination or if you data becomes stale immediately (default lib behaviour).

So assuming your data is a temporary representation of server state it would be better to include the filters in the query key so you would end up making different queries and having different independent cache entries to different filter combinations. This way:

  • You don't need selectors
  • You only fetch what you need
  • When you change the filters you have access to the cache data (if any) while react-query refetches in the background. This depends on how you configure react-query

1 Comment

Thanks for your answer. I asked react-query team and they said that the selector feature will be added in the next release
0

I am not aware of a builtin native selector solution, but You can achieve this with a custom hook.

function useMostPopularPosts(){
  const postsResult = useQuery(postsQueryParams)
  const mostPopularResult = useQuery(popularPostsQueryParams)

  if (!(postsResult.success && mostPopularResult.success)){
    return []; 
  }

  return postsResult.data.filter(
    post=> mostPopularResult.data.includes(post.id)
  )

 
}

function MostPopularPosts(){
  const popularPosts = usePopularPosts()

  return <>
    {
      popularPosts.map(post=>(
        <PostHighlight post={post} />
      ))
    }
  </>
}

Comments

0

Yes, react-query has a selector feature.

(1) You can achieve this by passing your filters in the query key array (the filters can stand alone or be grouped in an object). Each query key will lead to different results, and they are cached default by 5 minutes. Next time when you filter the list again, it can return data from the cache without fetching API again.


(2) react-query also provided an option named select, but it just customs the returned data (filter or just return a part of the object, etc.) but not affects what gets stored in the query cache (full data).

You can still use this latter way, but the most suitable is the former mentioned.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.