Tienda estatal
Lo mejor de Markup estado es el hecho de que es una API independiente que funciona muy bien con la propia plantilla.
Lo que esto le permite hacer es administrar el estado compartido/global fuera del componente e inyectarlos directamente en la plantilla o realizar efectos secundarios cuando sea necesario. Todo eso sin preocuparte por suscripciones y limpiezas.
Crear una tienda estatal
Tomemos, por ejemplo, este almacén estatal 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 puede ver, podemos crear un archivo dedicado a administrar un estado particular que queremos usar en varios lugares de nuestra aplicación.
Consumir el estado de la tienda
No tenemos que preocuparnos por la suscripción cuando se trata de representar estos datos, podemos inyectarlos directamente en la plantilla.
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>
`
}Es bastante fácil, para realizar algo cada vez que esta lista cambia, podemos usar el efecto.
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 acciones de tienda
Debido a que el almacén es simplemente un archivo, podemos exponer funciones que realizan cambios en los datos sin exponer la lógica o la complejidad del 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([])
}Estas acciones pueden ser las que quieras. ellos pueden
- almacenar datos en
localstorageoindexedDB; - ser asíncrono;
- llamar a las API de los servidores para guardar datos;
- realizar validaciones;
- mapear los datos;
- etc.
El almacenamiento de datos y la gestión del estado no tienen por qué ser complejos y todo lo que necesita a partir de aquí es utilizar las API disponibles en el entorno para hacer lo que quiera.
Mire este ejemplo de todo state store with localstorage.
editar este documento