DEV Community

Cover image for Hide useQuery
Sebastian Ruhleder
Sebastian Ruhleder

Posted on • Originally published at log.seruco.io

Hide useQuery

I always wrap React Query's useQuery hook in a custom hook and never use it directly within a component. To see why, let's have a look at an example:

function TodoList() {
  const { data: todos = [] } = useQuery(
    ['todos'],
    () => fetchTodos()
  );

  return (
    <ul>
      {todos.map(todo => (
        <li>{todo}</li>
      )}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

The TodoList component is quite simple: It fetches a list of to-dos from our backend and renders them within an unordered list. By using useQuery directly, this component has to:

  • specify a unique query key,
  • be aware of the fetchTodos() function,
  • and provide a sensible initial value [] while the request hasn't completed yet.

The component is intended to render a to-do list, yet it is responsible for very technical decisions like these. In contrast, let's encapsulate the use of useQuery in a custom hook:

function TodoList() {
  const todos = useTodos();

  return (
    <ul>
      {todos.map(todo => (
        <li>{todo}</li>
      )}
    </ul>
  );
}

function useTodos() {
  const { data: todos = [] } = useQuery(
    ['todos'],
    () => fetchTodos()
  );
  return todos;
}
Enter fullscreen mode Exit fullscreen mode

By introducing a custom useTodos() hook, we:

  • provide a layer abstraction by separating what we want to do (get a list of to-dos) from how we do it (by using React Query),
  • make the list of to-dos reusable throughout our application,
  • make it possible to easily switch React Query for a different library later on,
  • and improve the readability of our TodoList component.

The choice of a sensible query key, how a resource is fetched, and the configuration of useQuery's options are implementation details that should always be hidden from components that only want to consume the resource managed by it.

I've used this pattern for quite a while, both in personal projects and at work. It has served me tremendously well. The pattern ties in with and is a concrete instance of Kyle Shevlin's great post useEncapsulation, which I can highly recommend for a more general view on this topic.

Top comments (0)