使用mobx入门

mobx是和redux,vuex一样的状态管理工具,但是mobx更接近于面向对象的风格相比redux更易懂(个人觉得)

本代码介绍了函数组件和class组件的两种写法,大概代码如下:

第一步需要安如下插件:

mobx   
mobx-react
react-app-rewired或者@craco/craco
个人觉得克拉克好像更好用一点,更贴近于vue.config.js的写法

第二步,建立store,如圖:

其中store是一些action就是處理數據的一些方法,entity就是數據的實體,以user为例代码如下:

entity.js

//store的类,要声明一下字段的类型
export const UserInfo = {
  name:String,
  password:String
}

store:

import { action, makeObservable, observable } from "mobx";

class userMobx {
  constructor() {
    makeObservable(this);
  }
  //默认属性值
  @observable userInfo = {};

  //箭头函数确保this 指向不变,不使用箭头函数在函数组件可能会出现this是undefined的情况
  @action setUserInfo=(info)=> {
    //修改后会存入mobx的状态中
    this.userInfo = info;
  }
}

export default new userMobx();

mobx的store:

import userMobx from "./User/store";
import accountMobx from './Account/store'

const store = {
  userMobx,
  accountMobx
};

export default store;

然后再index.js中注入

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'mobx-react'
import './index.css';
import App from './App';
import store from './Mobx/index'

ReactDOM.render(
  // <React.StrictMode>
    <Provider {...store}>
      <App />
    </Provider>,
  // </React.StrictMode>,
  document.getElementById('root')
);

最后可以运行的完整例子:

import React, { useState } from "react";
import { inject, observer } from "mobx-react";

function Test(props) {
  const [user, setUser] = useState({ name: "张三", age: 18, sex: "男" });

  const modifyUserInfo = () => {
    const {userMobx:{setUserInfo}} =props
    setUserInfo(user)
  };

  const setUserState = (key, val) => {
    let obj = {
      ...user,
      [key]: val.target.value,
    };
    setUser(obj);
  };
  const {
    userMobx: { userInfo },
  } = props;
  return (
    <>
      <div>
        <div>用户原信息:</div>
        <ul>
          <li>
            <span>姓名:</span>
            <span>{userInfo.name}</span>
          </li>
          <li>
            <span>年龄:</span>
            <span>{userInfo.age}</span>
          </li>
          <li>
            <span>性别:</span>
            <span>{userInfo.sex}</span>
          </li>
        </ul>
      </div>
      <div>
        <div>要修改的信息:</div>
        <ul>
          <li>
            <span>姓名:</span>
            <span>
              <input
                type="text"
                value={user.name}
                onChange={(val) => setUserState("name", val)}
              />
            </span>
          </li>
          <li>
            <span>年龄:</span>
            <input
              type="text"
              value={user.age}
              onChange={(val) => setUserState("age", val)}
            />
          </li>
          <li>
            <span>性别:</span>
            <input
              type="text"
              value={user.sex}
              onChange={(val) => setUserState("sex", val)}
            />
          </li>
        </ul>
        <button onClick={modifyUserInfo}>修改信息</button>
      </div>
    </>
  );
}
/**
 * 函数组件不可以写注解的方式,可以使用如下写法注入store,只有一个的时候也可以使用inject("store的名字")这样的字符串写法
 * 使用类的写法时,可以用装饰器的写法进行如下格式的书写
 * @inject('store')//这里是注入 Provider store={userStore}中的那个store
 * 參數也可以使用方法返回一个json
 * @observer
 * class Test1 extends React.Component {...}
 */
export default inject(store=>{
  return {
    userMobx:store.userMobx,
    accountMobx:store.accountMobx
  }
})(observer(Test));

这里要注意的是react目前不支持装饰器(JAVA叫注解,C#叫序列化标记)的语法,所以要是用

react-app-rewired

或者克拉克.js

这里对两个分别做一下简要说明,克拉克:

新建一个

craco.config.js

然后加入如下代码:

module.exports = {
  babel: {
    //用来支持装饰器
    plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
  },
};

其中

@babel/plugin-proposal-decorators

需要安装,
package.json要换成如下的配置:
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

 

react-app-rewired:
新建 config-overrides.js
然后加入如下代码:
const { override, addDecoratorsLegacy } = require('customize-cra')
module.exports = override(addDecoratorsLegacy()),
其中
customize-cra
需要安装

posted @ 2021-06-18 10:17  洛晨随风  阅读(672)  评论(0编辑  收藏  举报