Loading...
Loading...
Compare original and translation side by side
StoreDerivedEffectbatch@tanstack/store@tanstack/react-storeStoreDerivedEffectbatch@tanstack/store@tanstack/react-storenpm install @tanstack/store @tanstack/react-storenpm install @tanstack/store @tanstack/react-storeimport { Store } from '@tanstack/store'
const countStore = new Store(0)
const userStore = new Store<{ name: string; email: string }>({
name: 'Alice',
email: 'alice@example.com',
})import { Store } from '@tanstack/store'
const countStore = new Store(0)
const userStore = new Store<{ name: string; email: string }>({
name: 'Alice',
email: 'alice@example.com',
})// Function updater (immutable update)
countStore.setState((prev) => prev + 1)
userStore.setState((prev) => ({ ...prev, name: 'Bob' }))// 函数式更新器(不可变更新)
countStore.setState((prev) => prev + 1)
userStore.setState((prev) => ({ ...prev, name: 'Bob' }))const unsub = countStore.subscribe(() => {
console.log('Count:', countStore.state)
})
// Cleanup
unsub()const unsub = countStore.subscribe(() => {
console.log('Count:', countStore.state)
})
// 清理订阅
unsub()const store = new Store(initialState, {
// Custom update function
updateFn: (prevValue) => (updater) => {
return updater(prevValue) // custom logic
},
// Callback on subscribe
onSubscribe: (listener, store) => {
console.log('New subscriber')
return () => console.log('Unsubscribed')
},
// Callback on every update
onUpdate: () => {
console.log('State updated:', store.state)
},
})const store = new Store(initialState, {
// 自定义更新函数
updateFn: (prevValue) => (updater) => {
return updater(prevValue) // 自定义逻辑
},
// 订阅时的回调
onSubscribe: (listener, store) => {
console.log('新订阅者加入')
return () => console.log('订阅已取消')
},
// 每次更新时的回调
onUpdate: () => {
console.log('状态已更新:', store.state)
},
})store.state // Current state
store.prevState // Previous state
store.listeners // Set of listener callbacksstore.state // 当前状态
store.prevState // 上一状态
store.listeners // 监听器回调集合import { Store, Derived } from '@tanstack/store'
const count = new Store(5)
const multiplier = new Store(2)
const doubled = new Derived({
deps: [count, multiplier],
fn: ({ currDepVals }) => currDepVals[0] * currDepVals[1],
})
// MUST mount to activate
const unmount = doubled.mount()
console.log(doubled.state) // 10
count.setState(() => 10)
console.log(doubled.state) // 20
// Cleanup
unmount()import { Store, Derived } from '@tanstack/store'
const count = new Store(5)
const multiplier = new Store(2)
const doubled = new Derived({
deps: [count, multiplier],
fn: ({ currDepVals }) => currDepVals[0] * currDepVals[1],
})
// 必须调用mount()以激活
const unmount = doubled.mount()
console.log(doubled.state) // 10
count.setState(() => 10)
console.log(doubled.state) // 20
// 清理
unmount()const accumulated = new Derived({
deps: [count],
fn: ({ prevVal, currDepVals }) => {
return currDepVals[0] + (prevVal ?? 0)
},
})const accumulated = new Derived({
deps: [count],
fn: ({ prevVal, currDepVals }) => {
return currDepVals[0] + (prevVal ?? 0)
},
})const filtered = new Derived({
deps: [dataStore, filterStore],
fn: ({ currDepVals }) => currDepVals[0].filter(matchesFilter(currDepVals[1])),
})
const sorted = new Derived({
deps: [filtered, sortStore],
fn: ({ currDepVals }) => [...currDepVals[0]].sort(comparator(currDepVals[1])),
})
const paginated = new Derived({
deps: [sorted, pageStore],
fn: ({ currDepVals }) => currDepVals[0].slice(
currDepVals[1].offset,
currDepVals[1].offset + currDepVals[1].limit,
),
})const filtered = new Derived({
deps: [dataStore, filterStore],
fn: ({ currDepVals }) => currDepVals[0].filter(matchesFilter(currDepVals[1])),
})
const sorted = new Derived({
deps: [filtered, sortStore],
fn: ({ currDepVals }) => [...currDepVals[0]].sort(comparator(currDepVals[1])),
})
const paginated = new Derived({
deps: [sorted, pageStore],
fn: ({ currDepVals }) => currDepVals[0].slice(
currDepVals[1].offset,
currDepVals[1].offset + currDepVals[1].limit,
),
})import { Store, Effect } from '@tanstack/store'
const count = new Store(0)
const logger = new Effect({
deps: [count],
fn: () => {
console.log('Count changed:', count.state)
// Optionally return cleanup function
return () => console.log('Cleaning up')
},
eager: false, // true = run immediately on mount
})
const unmount = logger.mount()
count.setState(() => 1) // logs: "Count changed: 1"
unmount()import { Store, Effect } from '@tanstack/store'
const count = new Store(0)
const logger = new Effect({
deps: [count],
fn: () => {
console.log('Count 已变更:', count.state)
// 可选返回清理函数
return () => console.log('正在清理')
},
eager: false, // true = 挂载后立即执行
})
const unmount = logger.mount()
count.setState(() => 1) // 输出: "Count changed: 1"
unmount()const timerEffect = new Effect({
deps: [intervalStore],
fn: () => {
const id = setInterval(() => { /* ... */ }, intervalStore.state)
return () => clearInterval(id) // cleanup on next run or unmount
},
})const timerEffect = new Effect({
deps: [intervalStore],
fn: () => {
const id = setInterval(() => { /* ... */ }, intervalStore.state)
return () => clearInterval(id) // 下次执行或卸载时清理
},
})import { batch } from '@tanstack/store'
// Subscribers fire only once with final state
batch(() => {
countStore.setState(() => 1)
nameStore.setState(() => 'Alice')
settingsStore.setState((prev) => ({ ...prev, theme: 'dark' }))
})import { batch } from '@tanstack/store'
// 订阅者只会在最终状态时触发一次
batch(() => {
countStore.setState(() => 1)
nameStore.setState(() => 'Alice')
settingsStore.setState((prev) => ({ ...prev, theme: 'dark' }))
})import { useStore } from '@tanstack/react-store'
// Subscribe to full state
function Counter() {
const count = useStore(countStore)
return <button onClick={() => countStore.setState((c) => c + 1)}>{count}</button>
}
// Subscribe with selector (performance optimization)
function UserName() {
const name = useStore(userStore, (state) => state.name)
return <span>{name}</span>
}
// Subscribe to Derived
function DoubledDisplay() {
const value = useStore(doubledDerived)
return <span>{value}</span>
}import { useStore } from '@tanstack/react-store'
// 订阅完整状态
function Counter() {
const count = useStore(countStore)
return <button onClick={() => countStore.setState((c) => c + 1)}>{count}</button>
}
// 带选择器的订阅(性能优化)
function UserName() {
const name = useStore(userStore, (state) => state.name)
return <span>{name}</span>
}
// 订阅Derived
function DoubledDisplay() {
const value = useStore(doubledDerived)
return <span>{value}</span>
}import { useStore } from '@tanstack/react-store'
import { shallow } from '@tanstack/react-store'
function TodoList() {
// Without shallow: re-renders on ANY state change (new object ref)
// With shallow: only re-renders when items actually change
const items = useStore(todosStore, (state) => state.items, shallow)
return <ul>{items.map(/* ... */)}</ul>
}import { useStore } from '@tanstack/react-store'
import { shallow } from '@tanstack/react-store'
function TodoList() {
// 不使用shallow:任何状态变更都会触发重渲染(新对象引用)
// 使用shallow:仅当items实际变更时才重渲染
const items = useStore(todosStore, (state) => state.items, shallow)
return <ul>{items.map(/* ... */)}</ul>
}function MyComponent() {
useEffect(() => {
const unmountDerived = myDerived.mount()
const unmountEffect = myEffect.mount()
return () => {
unmountDerived()
unmountEffect()
}
}, [])
const value = useStore(myDerived)
return <span>{value}</span>
}function MyComponent() {
useEffect(() => {
const unmountDerived = myDerived.mount()
const unmountEffect = myEffect.mount()
return () => {
unmountDerived()
unmountEffect()
}
}, [])
const value = useStore(myDerived)
return <span>{value}</span>
}// stores/counter.ts
import { Store, Derived } from '@tanstack/store'
export const counterStore = new Store(0)
export const doubledCount = new Derived({
deps: [counterStore],
fn: ({ currDepVals }) => currDepVals[0] * 2,
})
// Actions as plain functions
export function increment() {
counterStore.setState((c) => c + 1)
}
export function reset() {
counterStore.setState(() => 0)
}// stores/counter.ts
import { Store, Derived } from '@tanstack/store'
export const counterStore = new Store(0)
export const doubledCount = new Derived({
deps: [counterStore],
fn: ({ currDepVals }) => currDepVals[0] * 2,
})
// 以普通函数定义操作
export function increment() {
counterStore.setState((c) => c + 1)
}
export function reset() {
counterStore.setState(() => 0)
}| Framework | Package | Hook/Composable |
|---|---|---|
| React | | |
| Vue | | |
| Solid | | |
| Angular | | |
| Svelte | | |
| 框架 | 包名 | Hook/组合式函数 |
|---|---|---|
| React | | |
| Vue | | |
| Solid | | |
| Angular | | |
| Svelte | | |
useStoreshallowmount()setStatebatchfnuseStoreshallowmount()setStatebatchfnmount()store.statesetStateshallowuseStoreeager: truemount()store.statesetStateshallowuseStoreeager: true