Reputation: 1328
Hi guys i was just trying out mobx today and made a Todo List with it, the problem is the list isn't updating here after the item is removed from the list even though i had made observer and observable. You can also directly check my code here at CodeSanbox .It's a basic todo app
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);
So as i click remove button, the action "removeTodo" gets fired up the todo is removed from the list i can check that on console but it istn't updating in the UI part
Upvotes: 0
Views: 715
Reputation: 8081
With Mobx v6
simply setting decorators
is not enough anymore. You also need to call makeObservable
or makeAutoObservable
in the class constructor.
import { observable, action, computed, reaction,makeAutoObservable } from "mobx"
constructor() {
makeAutoObservable(this)
reaction(() => this.todos, _ => console.log(this.todos.length))
}
Upvotes: 1