빠른 시작
TanStack DB는 API를 위한 반응형 로컬 우선 스토어입니다. 모든 뷰에 사용자 지정 엔드포인트를 만드는 작업을 중단하고 컴포넌트에 필요한 방식으로 데이터를 쿼리합니다. 이 예시에서는 다음 방법을 보여줍니다:
- TanStack Query를 사용하여 컬렉션에 데이터 로드
- 매우 빠른 라이브 쿼리로 데이터 쿼리
- 즉각적인 낙관적 업데이트로 데이터 뮤테이션
import {
DbClient,
DbProvider,
collectionOptions,
eq,
useDbClient,
useLiveQuery,
} from '@tanstack/react-db'
import { QueryClient } from '@tanstack/query-core'
import { queryCollectionOptions } from '@tanstack/query-db-collection'
const queryClient = new QueryClient()
const dbClient = new DbClient({ queryClient })
// Define a stable collection descriptor that loads data using TanStack Query
const todoCollection = collectionOptions('todos', (client) =>
queryCollectionOptions({
id: 'todos',
queryKey: ['todos'],
queryClient: client.requireDependency<QueryClient>('queryClient'),
queryFn: async () => {
const response = await fetch('/api/todos')
return response.json()
},
getKey: (item) => item.id,
onUpdate: async ({ transaction }) => {
const { original, modified } = transaction.mutations[0]
await fetch(`/api/todos/${original.id}`, {
method: 'PUT',
body: JSON.stringify(modified),
})
},
})
)
function useTodoCollection() {
return useDbClient().collection(todoCollection)
}
function Todos() {
const todosCollection = useTodoCollection()
// Live query that updates automatically when data changes
const { data: todos } = useLiveQuery({
query: (q) =>
q.from({ todo: todoCollection })
.where(({ todo }) => eq(todo.completed, false))
.orderBy(({ todo }) => todo.createdAt, 'desc'),
})
const toggleTodo = (todo) => {
// Instantly applies optimistic state, then syncs to server
todosCollection.update(todo.id, (draft) => {
draft.completed = !draft.completed
})
}
return (
<ul>
{todos.map((todo) => (
<li key={todo.id} onClick={() => toggleTodo(todo)}>
{todo.text}
</li>
))}
</ul>
)
}
function App() {
return (
<DbProvider client={dbClient}>
<Todos />
</DbProvider>
)
}
이제 컬렉션, 라이브 쿼리 및 낙관적 뮤테이션을 사용할 수 있습니다! 이를 더 자세히 살펴보겠습니다.
SSR로 구축하는 경우 이 빠른 시작 후에 SSR 및 Hydration 가이드를 참조할 수 있습니다. 간단히 말하면 SSR 앱은 안정적인 collectionOptions(...) 디스크립터를 사용하고, 서버에서 요청 범위의 DbClient를 통해 이를 구체화한 다음, React 훅이 DB에서 읽기 전에 명시적 컬렉션 행 또는 미리 로드된 라이브 쿼리 결과로 브라우저의 DbClient를 하이드레이션합니다.
설치
npm install @tanstack/react-db @tanstack/query-db-collection @tanstack/query-core
1. 컬렉션 만들기
컬렉션은 데이터를 저장하고 영속성을 처리합니다. queryCollectionOptions는 TanStack Query를 사용하여 데이터를 로드하고 서버 동기화를 위한 뮤테이션 핸들러를 정의합니다:
const todoCollection = collectionOptions('todos', (client) =>
queryCollectionOptions({
id: 'todos',
queryKey: ['todos'],
queryClient: client.requireDependency<QueryClient>('queryClient'),
queryFn: async () => {
const response = await fetch('/api/todos')
return response.json()
},
getKey: (item) => item.id,
// Handle all CRUD operations
onInsert: async ({ transaction }) => {
const { modified: newTodo } = transaction.mutations[0]
await fetch('/api/todos', {
method: 'POST',
body: JSON.stringify(newTodo),
})
},
onUpdate: async ({ transaction }) => {
const { original, modified } = transaction.mutations[0]
await fetch(`/api/todos/${original.id}`, {
method: 'PUT',
body: JSON.stringify(modified),
})
},
onDelete: async ({ transaction }) => {
const { original } = transaction.mutations[0]
await fetch(`/api/todos/${original.id}`, { method: 'DELETE' })
},
})
)
위의 queryKey는 컬렉션을 로드하기 위한 TanStack Query의 캐시 키입니다.
아래의 React 라이브 쿼리는 구조화된 쿼리 IR에서 자체 식별자를 파생합니다.
2. 컬렉션 구체화
컨텍스트의 DbClient를 사용하여 디스크립터를 구체화합니다. 작은 컬렉션 훅을 사용하면 컴포넌트에서 클라이언트 조회를 반복하지 않아도 됩니다:
function useTodoCollection() {
return useDbClient().collection(todoCollection)
}
3. 라이브 쿼리로 쿼리하기
라이브 쿼리는 데이터가 변경되면 반응형으로 업데이트됩니다. 필터링, 정렬, 조인 및 변환을 지원합니다. React 훅은 기본적으로 구조화된 쿼리에서 쿼리 식별자를 파생하므로 일반 빌더 쿼리에는 별도의 queryKey가 필요하지 않습니다:
function TodoList() {
// Basic filtering and sorting
const { data: incompleteTodos } = useLiveQuery({
query: (q) =>
q.from({ todo: todoCollection })
.where(({ todo }) => eq(todo.completed, false))
.orderBy(({ todo }) => todo.createdAt, 'desc'),
})
// Transform the data
const { data: todoSummary } = useLiveQuery({
query: (q) =>
q.from({ todo: todoCollection })
.select(({ todo }) => ({
id: todo.id,
summary: `${todo.text} (${todo.completed ? 'done' : 'pending'})`,
priority: todo.priority || 'normal'
})),
})
return <div>{/* Render todos */}</div>
}
4. 낙관적 뮤테이션
뮤테이션은 즉시 적용되고 서버와 동기화됩니다. 서버 요청이 실패하면 변경 사항이 자동으로 롤백됩니다:
function TodoActions({ todo }) {
const todosCollection = useTodoCollection()
const addTodo = () => {
todosCollection.insert({
id: crypto.randomUUID(),
text: 'New todo',
completed: false,
createdAt: new Date(),
})
}
const toggleComplete = () => {
todosCollection.update(todo.id, (draft) => {
draft.completed = !draft.completed
})
}
const updateText = (newText) => {
todosCollection.update(todo.id, (draft) => {
draft.text = newText
})
}
const deleteTodo = () => {
todosCollection.delete(todo.id)
}
return (
<div>
<button onClick={addTodo}>Add Todo</button>
<button onClick={toggleComplete}>Toggle</button>
<button onClick={() => updateText('Updated!')}>Edit</button>
<button onClick={deleteTodo}>Delete</button>
</div>
)
}
다음 단계
이제 TanStack DB의 기본 사항을 이해했습니다! 컬렉션은 데이터를 로드하고 영속화하며, 라이브 쿼리는 반응형 뷰를 제공하고, 뮤테이션은 자동 서버 동기화와 함께 즉각적인 피드백을 제공합니다.
다음 항목에 대한 자세한 내용은 문서에서 확인할 수 있습니다: