mobx5.x升级到mobx6.x
mobx

环境:

  • mobx 6.x
  • mobx-react 7.x

在最近的一个项目中,使用mobx作为状态管理。用法是按照5.x的用法来的,但是更新了值之后,组件并没有刷新。查了很多方案,都是用React.createContext来实现的,虽然官网有类似的用法,但是,如果是老项目,总不能全不都去改了吧?所以还是要在原来的基础上寻找解决方案。最后还是在官方文档上找到了相关的说明。
https://mobx.js.org/migrating-from-4-or-5.html
https://michel.codes/blogs/mobx6

我们根据这两个文章的内容写个demo测试。
工程结构如下:
image10.png

stores/count.store.js

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

export default class CountStore{
    constructor() {
        makeObservable(this, {
            count: observable,
            completedCount: computed,
            add: action
        });
    }
    count = 0;
    get completedCount() {
        return this.count;
    }

    add() {
        this.count = this.count+1;
    }
}

最关键的就是这里了,不能用之前的那种修饰符的写法
stores/index.js

import CountStore from "./count.store";

export default {
    countStore: new CountStore()
}

然后我们写两个组件,一个用class写法 一个用kooks写法
a.js

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

@inject('countStore')
@observer
class A extends React.Component{
    render() {
        const {countStore} = this.props;
        debugger
        return (<div>
            <div>A</div>
            <div>数量:{countStore.count}    <button onClick={()=>countStore.add()}>+</button></div>
        </div>)
    }
}
export default A;

b.js

import { inject,observer } from "mobx-react"

const B = ({countStore})=>{
    return <div>
        <div>B</div>
        <div>数量:{countStore.count}    <button onClick={()=>countStore.add()}>+</button></div>
    </div>
}
export default inject('countStore')(observer(B))

再写一个父组件
App.js

import React from "react"
import A from "./components/a";
import B from "./components/b";
import "./App.css"
import { inject, observer } from "mobx-react";

const { Route, Link } = require("react-router-dom");

const App = inject('countStore')(observer(class App extends React.Component {

  render(){
    const {countStore} = this.props;
    return (
      <div className={`App`}>
          <div className={`nav`}>
            <div><Link to={`/`}>a</Link></div>
            <div><Link to={`/b`}>b</Link></div>
            <div>数量:{countStore.count}    <button onClick={()=>countStore.add()}>+</button></div>
          </div>
        <div>
          <Route path={`/`} exact component={A} />
          <Route path={`/b`} exact component={B} />
        </div>
      </div>
    );
  }
}));

export default App;

配置入口文件
index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {HashRouter} from 'react-router-dom'
import reportWebVitals from './reportWebVitals';
import App from './App';
import { Provider } from 'mobx-react';
import stores from "./stores";
ReactDOM.render(
  <React.StrictMode>
    <Provider {...stores}>
    <HashRouter>
      <App/>
    </HashRouter>
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);
reportWebVitals();

另外,babel我还加了这个配置

plugins: [
  ['@babel/plugin-proposal-decorators', { legacy: true }],
  [
    "@babel/plugin-proposal-class-properties",
    {
      "loose":false
    }
  ]
]

运行看效果
1.gif

暂无评论