Skip to content

TanStack Query plugin

The built in syncedFetch and synced plugins should include all you need for remote sync, but this plugin can help when integrating into or migrating from an existing Query-based infrastructure.

This plugin takes all of the normal Query parameters, but it updates an observable instead of triggering a re-render. The queryKey can be a function that returns a key array dependent on some observabes. If those observables change it will update the queryKey and re-run with the new key. That makes it super easy to do pagination, for example.

There are two ways to use this plugin:

1. React Hook

The useObservableSyncedQuery hook takes the normal Query parameters for the query and mutation, and additionally just needs a queryClient.

import { useObservableSyncedQuery } from '@legendapp/state/sync-plugins/tanstack-react-query';
import { useQueryClient } from '@tanstack/react-query';
const Component = observer(function Component() {
const queryClient = useQueryClient()
const state$ = useObservableSyncedQuery({
queryClient,
query: {
queryKey: ['todos'],
queryFn: async () => {
return fetch('https://reqres.in/api/users/1').then((v) => v.json())
},
},
mutation: {
mutationFn: async (variables) => {
return fetch(
'https://reqres.in/api/users/1',
{ body: JSON.stringify(variables), method: 'POST' }
)
},
},
})
// Call get to start the sync
const state = state$.get()
// Or bind an input directly to a property, which will also start the sync
return (
<div>
<Reactive.input $value={state$.first_name} />
</div>
)
})

2. Outside of React

syncedQuery takes the normal Query parameters for the query and mutation, and additionally just needs a queryClient. It uses @tanstack/query-core and does not need to be used within React components.

import { syncedQuery } from '@legendapp/state/sync-plugins/tanstack-query';
import { QueryClient } from '@tanstack/react-query';
const queryClient = new QueryClient()
const state$ = observable(syncedQuery({
queryClient,
query: {
queryKey: ['todos'],
queryFn: async () => {
return fetch('https://reqres.in/api/users/1').then((v) => v.json())
},
},
mutation: {
mutationFn: async (variables) => {
return fetch(
'https://reqres.in/api/users/1',
{ body: JSON.stringify(variables), method: 'POST' }
)
},
},
}))
observe(() => {
// get() the value to start syncing, and it will be reactive to updates coming in
console.log(state$.get())
})