react项目中使用mobx

9 项目中使用mobx进行状态管理

mobx有以下几个概念:observable,action,reaction,observer。

MobX 支持单向数据流,也就是动作改变状态,而状态的改变会更新所有受影响的视图

Action, State, View

Observable 存放状态

const appState = observable({
  name: '麦乐',
  height: '168cm'
})

Actions 更新state

主要用来更新状态的,需要把更新状态的函数传入action()函数中,action()函数会返回一个新的函数  。

appState.resetTimer = action(function reset() {
    appState.name = 高秀;
});

Provider  挂载store

import { store } from './appStore'
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'mobx-react'

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

Inject函数注入store 

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

@inject('store')
@observer
class App extends React.Compnent {
  render() {
    const { store } = this.props
  }
}

Observer 观察数据改变 重新渲染

observer()会自动跟踪render方法里面消费的那些observable state。只要其中任何的observable发生了改变,re-render就会发生。 

 先来解决一下装饰器问题

VS CODE对装饰器报错

文件  > 首选项  >  设置(ctrl + ,) 勾选一下就可以了

搜索experimentalDecorators,设置"javascript.implicitProjectConfig.experimentalDecorators": true,该选项默认为false,需要改为true

npm install --save @babel/plugin-proposal-decorators
// package.json文件下面的babel选项中加入plugin属性
"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      ["@babel/plugin-proposal-decorators", { "legacy": true }]
    ]
  },
// appStore.js
import { observable, action, runInAction, flow } from 'mobx'
import Axios from '../utils/request'
// observable就是封装了state
// const appStore = observable({
//   counter: 0
// })
// Actions 就是用来更新state的
// appStore.addCount = action(()=>{
//   appStore.counter += 1
// })
// appStore.subCount = action(()=>{
//   if (appStore.counter <= 0) return;
//   appStore.counter -= 1
// })

// use decorator 	packaging class
class appStore {
    // 存放状态
  @observable itemList = ['3']
  @observable counter = 0
  
// action函数
  @action
  addCount() {
    this.counter +=1
  }

  @action
  addItem(item) {
    if (this.itemList.indexOf(item) !== -1) return;
    this.itemList.push(item)
  }
  // 把class实例提前绑定在该方法
  @action.bound
  removeItem(item) {
    this.itemLis = this.itemList.filter((x, index)=>{
      return x !== item;
    })
  }
  // 异步数据请求
  @action.bound
  async query() {
    try {
      this.status = 'pending'
      const result = await Axios.get('/h5/misc/config')

      runInAction(() => {
        this.itemList = result.List
        this.counter = result.counter
      })
    } catch (e) {
      runInAction(() => this.status = 'failed')
      console.log(e)
    }
  }

  // <- note the star, this a generator function!
  // 多个数据请求
  @action.bound
  loadEquity = flow(function* () {
    // yield instead of await
    try {
      const account = yield Axios.get('/h5/misc/config')
      const summary = yield Axios.get('/h5/misc/config')
      const equityList = yield Axios.get('/h5/misc/config')
      // the asynchronous blocks will automatically be wrapped in actions and can modify state
      this.accountId = account.accountId
      this.balance = account.balance
      this.summary = summary
      this.cardData = equityList
    } catch (e) {
      this.rpcError = true
    }
  })
}

export default new appStore();
// 根目录下的index.js 也就是入口文件 挂载storre
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import './index.scss'
// 把store传递到子孙组件中, 这样就可以在组件中直接inject()
import {Provider} from 'mobx-react'
import AppStore from './mobx/appStore'

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

//  +++++ 加入+++++
if (module.hot) {
    module.hot.decline('./App');
}
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
// Home下面的 index.js文件
import React from 'react';
import logo from '../../logo.svg';
import './index.scss';
import Footer from "../../publicComponents/Footer"
import Axios from "../../utils/request";
import { observer, inject } from "mobx-react"

/***
 * 有了observable来代表state,有了action来修改state,
 * 那么UI怎么消费state,并且响应state的变化呢。在react应用中,需要引入npm包mobx-react。
 * 它提供一个observer()方法来绑定react和mobx。observer()包裹一个react component从而生成一个高阶component(HoC)来自动响应observable state的改变。
 * observer()会自动跟踪render方法里面消费的那些observable state。
 * 只要其中任何的observable发生了改变,re-render就会发生。
 */


// 使store跟component链接起来 注入store
@inject('store')
// 装饰器decorator来封装component
@observer
class Home extends React.Component {
  constructor(props) {
    super(props)
    this.addCount = this.addCount.bind(this)
  }
  componentDidMount () {
    Axios.get('/h5/misc/config').then((response) => {
      console.log(response);
    }).catch((err) => {
      console.log(err)
    })
  }
  addCount() {
    const { store } = this.props
    store.addCount()
  }
  render() {
    const { store } = this.props
    return (
      <div className="Home">
        <header className="Home-header">
          <img src={logo} className="Home-logo" alt="logo" />      
          <p onClick={this.addCount}>{store.counter}</p>
          <a
            className="Home-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn ss
          </a>
        </header>
        <Footer  History={this.props.history} selectedTab='blueTab' />
      </div>
    );
  }
}

export default Home;

https://github.com/artadmire/react-mobx

猜你喜欢

转载自blog.csdn.net/qq_41831345/article/details/90903352