本文共 3931 字,大约阅读时间需要 13 分钟。
在 React 应用中,处理异步任务是一个常见的挑战。Redux 和 MobX 都提供了处理异步数据的方法,但它们各有优劣。以下将详细介绍如何在 MobX 中实现异步数据加载,并与 Redux 的异步处理进行对比。
Redux 提供了一个名为 Thunk 的中间件,可以用来在 reducers 中定义异步操作。通过使用 dispatch
函数,可以将 actions 组合成一个 thunk 函数,这个函数可以执行异步操作,例如 API 请求,并在完成后通过 dispatch
发送一个 action 更新状态。
MobX 提供了两种异步处理方法:Saga 和 Thunk。MobX 的 Thunk 和 Redux 的 Thunk 有相似之处,但 MobX 的 Saga 更加强大,支持更复杂的异步操作,包括并发和错误处理。
npm install json-server axios
./src/todo.json{ "todos": [ { "id": 1, "title": "React", "completed": false }, { "id": 2, "title": "Angular", "completed": false }, { "id": 3, "title": "Vue", "completed": false } ]}
npm install axios
loadTodos
异步任务import { makeObservable, observable, action, computed, runInAction } from "mobx";import TodoViewStore from "./TodoViewStore";import axios from "axios";class TodoListStore { todos = []; filter = "all"; constructor(todos) { if (todos) this.todos = todos; makeObservable( this, { todos: observable, filter: observable, createTodo: action, deleteTodo: action, clear: action.bound, changeFilter: action.bound, unCompletedTodoCount: computed, filterTodos: computed } ); this.loadTodos(); } async loadTodos() { const todos = await axios.get("http://localhost:3005/todos").then(response => response.data); runInAction(() => this.todos.push(...todos.map(todo => new TodoViewStore(todo.title)))); }}
import TodoListStore from "./TodoStore/TodoListStore";import CounterStore from "./CounterStore/CounterStore";import { createContext, useContext } from "react";class RootStore { constructor() { this.counterStore = new CounterStore(); this.todoListStore = new TodoListStore(); }}const RootStoreContext = createContext();const RootStoreProvider = ({ store, children }) => ({children} );const useRootStore = () => useContext(RootStoreContext);export { RootStore, RootStoreProvider, useRootStore };
import { observer } from "mobx-react-lite";import { useRootStore } from "../../stores/RootStore";import { useTodoListStore } from "../../stores/TodoStore/TodoListStore";function TodoFooter() { const { todoListStore } = useRootStore(); const { filter, changeFilter } = todoListStore; return ( );}export default observer(TodoFooter);
autorun
进行数据监测import { observer } from "mobx-react-lite";import { useEffect } from "react";import { autorun } from "mobx";import axios from "axios";function TodoHeader() { const [title, setTitle] = useState(""); const { todoListStore } = useRootStore(); const handleAddTodo = (e) => { if (e.key === "Enter") { todoListStore.createTodo(title); setTitle(""); } }; return ();}export default observer(TodoHeader); todos
setTitle(event.target.value)} onKeyUp={handleAddTodo} />
在 loadTodos
方法中,使用 runInAction
将异步操作包裹在一个 Action 中执行,以确保在 MobX 环境下正确更新状态。
MobX 提供了 autorun
方法,可以用来监控状态的变化。例如,在 TodoHeader
组件中,可以使用 autorun
来跟踪 todoListStore
的状态变化。
为了避免 ESLint 警告,可以在项目根目录下创建 .eslintrc.js
文件:
module.exports = { plugins: ["react-hooks"], rules: { "react-hooks/exhaustive-deps": 0 }};
在 MobX 中,通过 runInAction
方法,可以在异步操作完成后触发一个 Action,用于更新状态。这与 Redux 的 Thunk 中间件类似,但 MobX 提供了更强大的异步控制能力。通过合理使用 autorun
和 reaction
方法,可以实现对状态的精细监测和响应。在实际开发中,合理配置 ESLint 并通过提供必要的上下文,可以确保组件的高效运行和良好的代码质量。
转载地址:http://ytbzz.baihongyu.com/