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:
// 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 = todosComo 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.
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.
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 stateDefinir 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.
// 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
- armazenar dados em
localstorageouindexedDB; - ser assíncrono;
- chamar APIs de servidores para salvar dados;
- realizar validações;
- mapear os dados;
- etc.
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