Magasin d'État
L'avantage de Markup state est le fait qu'il s'agit d'une API autonome qui fonctionne très bien avec le modèle lui-même.
Cela vous permet de gérer l'état partagé/global en dehors du composant et de les injecter directement dans le modèle ou d'effectuer des effets secondaires si nécessaire. Tout cela sans vous soucier des abonnements et des nettoyages.
Créer un magasin d'état
Prenons par exemple ce magasin d'état 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 = todosComme vous pouvez le voir, nous pouvons créer un fichier dédié à la gestion d'un état particulier que nous souhaitons utiliser à plusieurs endroits de notre application.
Consommer l'état du magasin
Nous n'avons pas à nous soucier de l'abonnement pour le rendu de ces données, nous pouvons les injecter directement dans le modèle.
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>
`
}Assez simple, pour effectuer quelque chose à chaque fois que cette liste change, nous pouvons simplement utiliser le effect.
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 stateDéfinir les actions du magasin
Étant donné que le magasin est simplement un fichier, nous pouvons exposer des fonctions qui effectuent des modifications dans les données sans exposer la logique ou la complexité de l'état.
// 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([])
}Ces actions peuvent être ce que vous voulez. Ils peuvent
- stocker les données dans
localstorageouindexedDB; - être asynchrone ;
- appeler les API des serveurs pour enregistrer les données ;
- effectuer des validations ;
- cartographier les données ;
- etc.
Le stockage des données et la gestion de l'état ne doivent pas nécessairement être complexes et il vous suffit d'utiliser les API facilement disponibles dans l'environnement pour faire ce que vous voulez.
Regardez cet exemple de magasin d'état todo avec stockage local.
modifier ce document