Skip to content

Getting started ​

Installation ​

Peer Dependency

@tanstack/query-core is a required peer dependency

bash
npm install @tanstack/query-core mobx-tanstack-query
bash
pnpm add @tanstack/query-core mobx-tanstack-query
bash
yarn add @tanstack/query-core mobx-tanstack-query

React Integration ​

This library is architecturally decoupled from React and doesn't provide React-specific hooks. For projects using React, we recommend leveraging the official @tanstack/react-query package instead. It offers first-class support for React hooks and follows modern React patterns.

The current React integration is implemented via MobX React bindings.

Alternatives ​

Creating instance of QueryClient ​

This is extended version of original QueryClient

ts
import { QueryClient } from "mobx-tanstack-query";
import { hashKey } from "@tanstack/query-core";

export const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      throwOnError: true,
      queryKeyHashFn: hashKey,
      refetchOnWindowFocus: true,
      refetchOnReconnect: true,
      staleTime: 10 * 60 * 1000,
      retry: (failureCount, error) => {
        if (error instanceof Response && error.status >= 500) {
          return failureCount < 3;
        }
        return false;
      },
    },
    mutations: {
      throwOnError: true,
    },
  },
});

Writing first queries ​

ts
import { Query } from "mobx-tanstack-query";

const fruitQuery = new Query({
  queryClient,
  queryFn: async ({ queryKey }) => {
    const response = await fetch(`/api/fruits/${queryKey[1]}`);
    return await response.json();
  },
  queryKey: ["fruits", "apple"],
});

Using with classes ​

ts
import { observable, action } from "mobx";
import { Query } from "mobx-tanstack-query";

class MyViewModel {
  abortController = new AbortController();

  @observable
  accessor fruitName = "apple";

  fruitQuery = new Query({
    queryClient,
    abortSignal: this.abortController.signal, // Don't forget about that!
    queryFn: async ({ queryKey }) => {
      const response = await fetch(`/api/fruits/${queryKey[1]}`);
      return await response.json();
    },
    options: () => ({
      enabled: !!this.fruitName,
      queryKey: ["fruits", this.fruitName],
    }),
  });

  @action
  setFruitName(fruitName: string) {
    this.fruitName = fruitName;
  }

  destroy() {
    this.abortController.abort();
  }
}

Using in React ​

tsx
import { observer } from "mobx-react-lite";

const App = observer(() => {
  return <div>{fruitQuery.data?.name}</div>;
});

Released under the MIT License.