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
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.
4 Comments
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.