Loja Estadual

A grande vantagem do Markup state é o fato de ser uma API independente que funciona muito bem com o próprio modelo.

O que isso permite que você faça é gerenciar o estado compartilhado/global fora do componente e injetá-lo diretamente no modelo ou executar efeitos colaterais quando necessário. Tudo isso sem se preocupar com assinaturas e limpezas.

Crie uma loja estadual

Tomemos por exemplo este armazenamento de estado 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

Como você pode ver, podemos criar um arquivo dedicado para gerenciar um determinado estado que queremos usar em vários locais de nossa aplicação.

Consumindo o estado da loja

Não precisamos nos preocupar com assinatura na hora de renderizar esses dados, podemos injetá-los diretamente no template.

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>
    `
}

Bastante fácil, para realizar algo sempre que esta lista mudar, podemos apenas usar o efeito.

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

Definir ações da loja

Como o armazenamento é simplesmente um arquivo, podemos expor funções que realizam alterações nos dados sem expor a lógica ou a complexidade do estado.

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([])
}

Essas ações podem ser o que você quiser. Eles podem

O armazenamento de dados e o gerenciamento de estado não precisam ser complexos e tudo o que você precisa a partir daqui é usar as APIs prontamente disponíveis no ambiente para fazer o que quiser.

Veja este exemplo de loja de estado de tarefas com armazenamento local.

editar este documento