mobx装饰器语法快速使用
1.安装准备
-
安装mobx
# mobx核心库 npm install --save mobx # mobx绑定react npm install mobx-react --save -
安装Babel插件
npm install @babel/plugin-proposal-decorators --save npm install @babel/plugin-proposal-class-properties --save -
当前安装的版本
{ "mobx": "^6.5.0", "mobx-react": "^7.3.0", }
2.启用装饰器语法支持
-
package.json文件配置方式
{ "eslintConfig": { "parserOptions": { "ecmaFeatures": { "legacyDecorators": true } } }, "babel": { "plugins": [ [ "@babel/plugin-proposal-decorators", { "legacy": true } ], [ "@babel/plugin-proposal-class-properties", { "loose": true } ] ] } }
3.编写一个store状态仓库
-
新建一个store文件夹
-
新建index.js文件
// index.js import { myStore } from "./myStore"; // 模块store状态库 const store = { myStore, }; export default store; -
新建模块store仓库
// myStore.js import axios from "axios"; import { observable, action, makeObservable, makeAutoObservable } from "mobx"; class MyStore { @observable timer = "2020"; @observable toDoList = []; @observable shopList = []; constructor() { // 捕获已经存在的对象属性并且使得它们可观察 makeObservable(this); } @action add = (params) => { this.toDoList.push(params); }; @action getList = () => { axios .get( 'url' ) .then((res) => { // 创建一个会被立即调用的临时 action。在异步进程中非常有用 // 将状态修改代码包装成动作 runInAction(() => { this.shopList = res.data.Data; }); }) .catch((err) => { }); }; } export const myStore = new MyStore();
4.store绑定到react
-
入口文件index.js
import React from "react"; import { createRoot } from "react-dom/client"; import App from "./App"; import { Provider } from "mobx-react"; import store from "./store"; // 为提供的创建一个 React 根container并返回根。 const root = createRoot(document.getElementById("root")); // 根可用于将 React 元素渲染到 DOM 中 root.render( <Provider {...store}> <App /> </Provider> ); -
组件中使用store中内容
// zujian.jsx import React, { Component } from "react"; import { observer, inject } from "mobx-react"; // inject:把store注入props中;observer使得组件可观察 @inject("myStore") @observer class Home extends Component { constructor(props) { super(props); this.state = {}; } componentDidMount() { let { myStore } = this.props; myStore.getList(); } onChlickHandle = (type) => { let { myStore } = this.props; switch (type) { case "add": // 发起一个action myStore.add("内容"); break; default: break; } }; render() { // 获取store中的值 let { shopList } = this.props.myStore; return ( <> <div>使用mobx</div> <div>{timer}</div> <button onClick={() => this.onChlickHandle("add")}> 添加 </button> <div> {shopList.map((item, i) => ( <div key={i}>{item}</div> ))} </div> </> ); } } export default Home;
5.一些问题
1.@observable 的数据存在不能在react组件中拿到和实时追踪更新?
-
因为低版本的mobx的@observer观察组件方法的组件只追踪render函数中的数据存取,所以可以在render中获取store中的值;
render() { // 获取store中的值 let { shopList } = this.props.myStore; return ( <> <div> {shopList.map((item, i) => ( <div key={i}>{item}</div> ))} </div> </> ); }
2.异步action中存在请求响应回调没被action包裹成动作导致状态不能及时对应修改
// 异步action最佳解决方案
getData = flow(function* () {
try {
const res = yield axios.get(
"url"
); // 用 yield 代替 await
console.log("getData", res);
// 异步代码块会被自动包装成动作并修改状态
this.projectsList = res.data.Data;
} catch (error) {
console.log("getData", err);
}
});