2

I need to do the filtering of movies in my component. Initial queries must be all movies. And after I click by button (button name for example historic/сomedy) my data, that I render in my react component must be changed to data from such queries with only history or сomedian movies. How can I realize this in react-query.

2 Answers 2

5

ideally, filtering should happen in the backend. That way, you can just make the name of the filtered movie part of your query key. React Query will then automatically refetch if the key changes, and also cache each entry filtering individually:

const [name, setName] = React.useState()
const { data } = useQuery(['movies', name], () => fetchMovies(name)))

if you don't do the filtering in the backend, you can just run the filtering on the data returned from useQuery:

const [name, setName] = React.useState()
const { data } = useQuery(['movies'], () => fetchMovies()))

const result = filterByName(data, name)

this would go well into a custom hook.

if referential stability is needed, you can wrap the result creation in useMemo:

const result = React.useMemo(() => filterByName(data, name), [data, name])

You can also leverage the select option of react-query:

const [name, setName] = React.useState()
const { data } = useQuery(
  ['movies'],
  () => fetchMovies()),
  {
    select: (response) => filterByName(response, name)
  }
)

in this case, the data returned from useQuery will already be filtered, and you don't have to worry about memoization.

Sign up to request clarification or add additional context in comments.

4 Comments

Ok, thank you very much for this detailed answer. I will try it.
Can you please elaborate on why filtering should happen on the backend? tyia
TkDodo, Will the select be momoized (wanted to confirm the below answer is corect by Rahul Malik?
I added a comment to the below answer.
1

I would like to add something to the TkDodo's answer, if you are using "select" option in react query, it WILL NOT memoize the results, for instance if you are doing an expensive calculation to transform your data inside the "select" function, it WILL RUN on every render and your app will end up being sluggish.

5 Comments

are you sure select isnt memoized? so it means that performance wise we should always alter the data inside the fn response instead of using the select
@Krembo0o it's not memorized by default, altho you can wrap it up with React.useCallback in case you are doing an expensive calculation. It will be a clean way of doing it.
You're conflating terms. the result of select is most definitely memoized. not only that, it's structurally shared. However, the select function itself is run on every render. You can wrap it in useCallback to avoid that. It's in my blog: tkdodo.eu/blog/…
@TkDodo can we reword your statement to "select function runs whenever queryFn succeeds or select functions identity changes" ?
but that sentence is most correct. An anonymous inline function changes its identity on every render, so it re-runs on ever render. This is also how memo from react works ..

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.