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 observables. 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 gets the queryClient from Context.
import { useObservableSyncedQuery } from '@legendapp/state/sync-plugins/tanstack-react-query';import { useQueryClient } from '@tanstack/react-query';import { use$ } from '@legendapp/state/react';
function Component() { const state$ = useObservableSyncedQuery({ query: { queryKey: ['user'], 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' } ) }, }, })
// get it with use$ to start the sync const state = use$(state$)
// Or bind an input directly to a property, which will also start the sync return ( <div> <$React.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: ['user'], 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())})