使用 react 和 typescript 通过 mobx 更新待办事项列表
Updating Todo list via mobx with react and typescript
大家好,我今天刚刚试用了 mobx 并用它制作了一个待办事项列表,问题是即使我已将观察者和可观察者从列表中删除后,列表也不会在此处更新。您也可以直接在 CodeSanbox 查看我的代码 here。这是一个基本的待办事项应用程序
Store.js
import { observable, action, computed, reaction } from "mobx"
import { createContext } from "react"
import { v4 as uuidv4 } from 'uuid';
export interface Todo {
id?: string;
title: string;
completed: boolean;
}
class TodoStore {
constructor() {
reaction(() => this.todos, _ => console.log(this.todos.length))
}
@observable todos: Todo[] = [
{ id: uuidv4(), title: "Item #1", completed: false },
{ id: uuidv4(), title: "Item #2", completed: false },
{ id: uuidv4(), title: "Item #3", completed: false },
{ id: uuidv4(), title: "Item #4", completed: false },
{ id: uuidv4(), title: "Item #5", completed: true },
{ id: uuidv4(), title: "Item #6", completed: false },
]
@action addTodo = (todo: Todo) => {
this.todos.push({ ...todo, id: uuidv4() })
}
@action toggleTodo = (id: string) => {
this.todos = this.todos.map(todo => {
if (todo.id === id) {
return {
...todo,
completed: !todo.completed,
}
}
return todo
})
}
@action removeTodo = (id: string) => {
console.log(id)
this.todos = this.todos.filter(todo => todo.id !== id)
console.log(this.todos)
}
@computed get info() {
return {
total: this.todos.length,
completed: this.todos.filter(todo => todo.completed).length,
notCompleted: this.todos.filter(todo => !todo.completed).length,
}
}
}
export default createContext(new TodoStore())
TodoList.js
import React, { useContext } from "react";
import TodoStore from "../stores/TodoStore";
import { observer } from "mobx-react-lite";
const TodoList = () => {
const todoStore = useContext(TodoStore);
const { todos, toggleTodo, removeTodo } = todoStore;
return (
<>
<div className="row">
<table className="table table-hover">
<thead className="thead-light">
<tr>
<th>Title</th>
<th>Completed?</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{todos.map(todo => (
<tr key={todo.id}>
<td>{todo.title}</td>
<td>{todo.completed ? "✅" : ""}</td>
<td>
<button
className="btn btn-sm btn-info"
onClick={_ => toggleTodo(todo.id!)}
>
Toggle
</button>
<button
className="btn btn-sm btn-danger"
onClick={_ => removeTodo(todo.id!)}
>
Remove
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</>
);
};
export default observer(TodoList);
因此,当我单击删除按钮时,操作“removeTodo”被启动,待办事项已从列表中删除我可以在控制台上检查,但它不会在 UI 部分更新
使用 Mobx v6
简单地设置 decorators
已经不够了。您还需要在 class 构造函数中调用 makeObservable
or makeAutoObservable
。
import { observable, action, computed, reaction,makeAutoObservable } from "mobx"
constructor() {
makeAutoObservable(this)
reaction(() => this.todos, _ => console.log(this.todos.length))
}
大家好,我今天刚刚试用了 mobx 并用它制作了一个待办事项列表,问题是即使我已将观察者和可观察者从列表中删除后,列表也不会在此处更新。您也可以直接在 CodeSanbox 查看我的代码 here。这是一个基本的待办事项应用程序
Store.js
import { observable, action, computed, reaction } from "mobx"
import { createContext } from "react"
import { v4 as uuidv4 } from 'uuid';
export interface Todo {
id?: string;
title: string;
completed: boolean;
}
class TodoStore {
constructor() {
reaction(() => this.todos, _ => console.log(this.todos.length))
}
@observable todos: Todo[] = [
{ id: uuidv4(), title: "Item #1", completed: false },
{ id: uuidv4(), title: "Item #2", completed: false },
{ id: uuidv4(), title: "Item #3", completed: false },
{ id: uuidv4(), title: "Item #4", completed: false },
{ id: uuidv4(), title: "Item #5", completed: true },
{ id: uuidv4(), title: "Item #6", completed: false },
]
@action addTodo = (todo: Todo) => {
this.todos.push({ ...todo, id: uuidv4() })
}
@action toggleTodo = (id: string) => {
this.todos = this.todos.map(todo => {
if (todo.id === id) {
return {
...todo,
completed: !todo.completed,
}
}
return todo
})
}
@action removeTodo = (id: string) => {
console.log(id)
this.todos = this.todos.filter(todo => todo.id !== id)
console.log(this.todos)
}
@computed get info() {
return {
total: this.todos.length,
completed: this.todos.filter(todo => todo.completed).length,
notCompleted: this.todos.filter(todo => !todo.completed).length,
}
}
}
export default createContext(new TodoStore())
TodoList.js
import React, { useContext } from "react";
import TodoStore from "../stores/TodoStore";
import { observer } from "mobx-react-lite";
const TodoList = () => {
const todoStore = useContext(TodoStore);
const { todos, toggleTodo, removeTodo } = todoStore;
return (
<>
<div className="row">
<table className="table table-hover">
<thead className="thead-light">
<tr>
<th>Title</th>
<th>Completed?</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{todos.map(todo => (
<tr key={todo.id}>
<td>{todo.title}</td>
<td>{todo.completed ? "✅" : ""}</td>
<td>
<button
className="btn btn-sm btn-info"
onClick={_ => toggleTodo(todo.id!)}
>
Toggle
</button>
<button
className="btn btn-sm btn-danger"
onClick={_ => removeTodo(todo.id!)}
>
Remove
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</>
);
};
export default observer(TodoList);
因此,当我单击删除按钮时,操作“removeTodo”被启动,待办事项已从列表中删除我可以在控制台上检查,但它不会在 UI 部分更新
使用 Mobx v6
简单地设置 decorators
已经不够了。您还需要在 class 构造函数中调用 makeObservable
or makeAutoObservable
。
import { observable, action, computed, reaction,makeAutoObservable } from "mobx"
constructor() {
makeAutoObservable(this)
reaction(() => this.todos, _ => console.log(this.todos.length))
}