Created
May 28, 2025 16:32
-
-
Save brandonbryant12/50809f6bba2953570f0258b6851b43e3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ### prefer tanstackquery over react query | |
| We use **TanStack Query (TQ)** for all new Backstage front-end work and phase out legacy React Query code. | |
| **Why TanStack Query?** | |
| * Framework-agnostic core (future-proof if we add non-React widgets) | |
| * Smaller, tree-shakable bundles → faster load times | |
| * Smarter cache & request de-duplication | |
| * First-class Suspense / SSR helpers | |
| * One DevTools panel that works everywhere | |
| --- | |
| #### Reading data (query) | |
| ```tsx | |
| import { useQuery } from '@tanstack/react-query'; | |
| function TodoCount() { | |
| const { data: todos = [], isLoading, isError } = useQuery({ | |
| queryKey: ['todos'], | |
| queryFn : () => fetch('/api/todos').then(r => r.json()), | |
| staleTime: 30_000, // fresh for 30 s | |
| }); | |
| if (isLoading) return <>Loading…</>; | |
| if (isError) return <>Error!</>; | |
| return <>Total todos: {todos.length}</>; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ### prefer tanstack query for front-end data fetching | |
| TanStack Query (TQ) is our **standard** way to fetch and cache data in Backstage plugins. | |
| While React Query v3 still works, all **new code must use TQ** and we will gradually migrate legacy files. | |
| --- | |
| #### Why TanStack Query? | |
| | Benefit | What it means for us | | |
| |---------|---------------------| | |
| | **Framework-agnostic core** | Same query cache even if we embed non-React UI in the future. | | |
| | **Smaller, tree-shakable bundles** | ~10-15 % smaller JS payloads → faster Backstage load times. | | |
| | **Automatic request de-duplication** | Multiple widgets that need the same data share **one** network call. | | |
| | **Suspense & SSR helpers** | Cleaner `<Suspense>` boundaries and easier server-side rendering. | | |
| | **Unified DevTools** | One debug panel (`@tanstack/react-query-devtools`) that works everywhere. | | |
| --- | |
| #### Read data (query) | |
| ```tsx | |
| import { useQuery } from '@tanstack/react-query'; | |
| export function TodoCount() { | |
| const { data: todos = [], isLoading, isError } = useQuery({ | |
| queryKey: ['todos'], | |
| queryFn : () => fetch('/api/todos').then(r => r.json()), | |
| staleTime: 30_000, // treat data as “fresh” for 30 s | |
| }); | |
| if (isLoading) return <>Loading…</>; | |
| if (isError) return <>Error!</>; | |
| return <>Total todos: {todos.length}</>; | |
| } | |
| Guidelines | |
| • Always use an array for queryKey (['todos'], ['catalog', id]…). | |
| • Prefer staleTime over polling; it avoids needless refetches. | |
| • Gate the fetch with enabled: flag when data depends on something else. | |
| ⸻ | |
| Write data (mutation) | |
| import { useMutation, useQueryClient } from '@tanstack/react-query'; | |
| export function AddTodoButton() { | |
| const qc = useQueryClient(); | |
| const addTodo = useMutation({ | |
| mutationFn: (text: string) => | |
| fetch('/api/todos', { method: 'POST', body: JSON.stringify({ text }) }), | |
| onSuccess: () => qc.invalidateQueries({ queryKey: ['todos'] }), | |
| }); | |
| return ( | |
| <button onClick={() => addTodo.mutate('Buy milk')}> | |
| Add “Buy milk” | |
| </button> | |
| ); | |
| } | |
| Use invalidateQueries (or setQueryData for optimistic updates) so every component watching ['todos'] refreshes automatically. | |
| ⸻ | |
| DevTools (development only) | |
| import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; | |
| {process.env.NODE_ENV === 'development' && ( | |
| <ReactQueryDevtools position="right" /> | |
| )} | |
| Toggle with Alt + D. | |
| ⸻ | |
| Migration tip | |
| Replace old imports only—most code stays unchanged. | |
| -import { useQuery } from 'react-query'; | |
| +import { useQuery } from '@tanstack/react-query'; | |
| Refactor files as you touch them; all new components must start with TanStack Query. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment