TanStack DB 是一个响应式客户端存储,用于构建超快的应用程序。本示例将向您展示如何
import { createCollection, eq, useLiveQuery } from '@tanstack/react-db'
import { queryCollectionOptions } from '@tanstack/query-db-collection'
// Define a collection that loads data using TanStack Query
const todoCollection = createCollection(
queryCollectionOptions({
queryKey: ['todos'],
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 Todos() {
// Live query that updates automatically when data changes
const { data: todos } = useLiveQuery((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
todoCollection.update(todo.id, (draft) => {
draft.completed = !draft.completed
})
}
return (
<ul>
{todos.map((todo) => (
<li key={todo.id} onClick={() => toggleTodo(todo)}>
{todo.text}
</li>
))}
</ul>
)
}
import { createCollection, eq, useLiveQuery } from '@tanstack/react-db'
import { queryCollectionOptions } from '@tanstack/query-db-collection'
// Define a collection that loads data using TanStack Query
const todoCollection = createCollection(
queryCollectionOptions({
queryKey: ['todos'],
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 Todos() {
// Live query that updates automatically when data changes
const { data: todos } = useLiveQuery((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
todoCollection.update(todo.id, (draft) => {
draft.completed = !draft.completed
})
}
return (
<ul>
{todos.map((todo) => (
<li key={todo.id} onClick={() => toggleTodo(todo)}>
{todo.text}
</li>
))}
</ul>
)
}
现在您已经拥有了集合、实时查询和乐观更新!让我们进一步分解。
npm install @tanstack/react-db @tanstack/query-db-collection
npm install @tanstack/react-db @tanstack/query-db-collection
集合存储您的数据并处理持久化。 queryCollectionOptions 使用 TanStack Query 加载数据并定义用于服务器同步的更新处理程序
const todoCollection = createCollection(
queryCollectionOptions({
queryKey: ['todos'],
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' })
},
})
)
const todoCollection = createCollection(
queryCollectionOptions({
queryKey: ['todos'],
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' })
},
})
)
实时查询在数据更改时做出响应式更新。它们支持过滤、排序、联接和转换
function TodoList() {
// Basic filtering and sorting
const { data: incompleteTodos } = useLiveQuery((q) =>
q.from({ todo: todoCollection })
.where(({ todo }) => eq(todo.completed, false))
.orderBy(({ todo }) => todo.createdAt, 'desc')
)
// Transform the data
const { data: todoSummary } = useLiveQuery((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>
}
function TodoList() {
// Basic filtering and sorting
const { data: incompleteTodos } = useLiveQuery((q) =>
q.from({ todo: todoCollection })
.where(({ todo }) => eq(todo.completed, false))
.orderBy(({ todo }) => todo.createdAt, 'desc')
)
// Transform the data
const { data: todoSummary } = useLiveQuery((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>
}
更新即时应用并同步到您的服务器。如果服务器请求失败,更改将自动回滚
function TodoActions({ todo }) {
const addTodo = () => {
todoCollection.insert({
id: crypto.randomUUID(),
text: 'New todo',
completed: false,
createdAt: new Date(),
})
}
const toggleComplete = () => {
todoCollection.update(todo.id, (draft) => {
draft.completed = !draft.completed
})
}
const updateText = (newText) => {
todoCollection.update(todo.id, (draft) => {
draft.text = newText
})
}
const deleteTodo = () => {
todoCollection.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>
)
}
function TodoActions({ todo }) {
const addTodo = () => {
todoCollection.insert({
id: crypto.randomUUID(),
text: 'New todo',
completed: false,
createdAt: new Date(),
})
}
const toggleComplete = () => {
todoCollection.update(todo.id, (draft) => {
draft.completed = !draft.completed
})
}
const updateText = (newText) => {
todoCollection.update(todo.id, (draft) => {
draft.text = newText
})
}
const deleteTodo = () => {
todoCollection.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 的基础知识!集合加载和持久化数据,实时查询提供响应式视图,而更新提供即时反馈和自动服务器同步。
探索文档以了解更多关于
您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。