国营商店

Markup state 的伟大之处在于它是一个独立的 API,可以与模板本身完美配合。

这允许您做的是管理远离组件的共享/全局状态,并将它们直接注入到模板中或在需要时执行副作用。所有这一切都无需担心订阅和清理。

创建状态存储

todos 状态存储为例:

typescript
// src/stores/todos.ts

type UUID = `${string}-${string}-${string}-${string}-${string}`

export interface Todo {
    id: UUID
    name: string
    description: string
    status: 'done' | 'pending' | 'removed'
    dateCreated: Date
    dateLastUpdated: Date
}

const [todos, updateTodos] = state<Todo[]>([])

export const todoList = todos

正如您所看到的,我们可以创建一个专用于管理我们想要在应用程序中的多个位置使用的特定状态的文件。

消费存储状态

在渲染这些数据时,我们不必担心订阅,我们可以将其直接注入到模板中。

javascript
import {todoList} from "./stores/todos"

const App = () => {

    const renderTodo = () => {...}

    // html will handle all subscribing and
    // unsubscribing from todoList state
    return html`
        <ul id="todos">
            ${repeat(todoList, renderTodo)}
        </ul>
    `
}

很简单,只要这个列表发生变化就执行一些操作,我们只需使用 effect 即可。

javascript
import { todoList } from './stores/todos'

const defaultTodosByStatus = { done: [], pending: [], removed: [] }

const [todosByStatus, updateTodosByStatus] = state(defaultTodosByStatus)

// effect will handle subscribing to the todoList state
const unsubFromEffect = effect(() => {
    updateTodosByStatus(
        todoList().reduce((acc, todo) => {
            if (!acc[todo.status]) {
                acc[todo.status] = []
            }

            acc[todo.status].push(todo)

            return acc
        }, defaultTodosByStatus)
    )
})

// call "unsubFromEffect" to unsubscribe from todoList state

定义商店操作

因为存储只是一个文件,所以我们可以公开执行数据更改的函数,而无需公开状态的逻辑或复杂性。

typescript
// src/stores/todos.ts

...

export const createTodo = (name: string) => {
  const dateCreated = new Date();
  const todo: Todo = {
    id: crypto.randomUUID(),
    name,
    description: "",
    status: "pending",
    dateCreated,
    dateLastUpdated: dateCreated
  }

  updateTodos(prev => [...prev, todo])
}

export const updateTodo = (id: UUID, data: Partial<Todo>) => {
    updateTodos(prev => prev.map(todo => {
        if(todo.id === id) {
            return {
                ...todo,
                name: data.name ?? todo.name,
                description: data.description ?? todo.description,
                status: data.status ?? todo.status,
                dateLastUpdated: new Date()
            }
        }

        return todo;
    }))
}

export const deleteTodo = (id: UUID) => {
    updateTodos(prev => prev.filter(todo => {
        return todo.id !== id;
    }))
}

export const clearTodos = () => {
    updateTodos([])
}

这些操作可以是您想要的任何操作。他们可以

数据存储和状态管理不必很复杂,您所需要的只是使用环境中现成的 API 来执行您想要的操作。

看一下这个 todo state store with localstorage 的示例。

编辑本文档