title: 使用 Mobx

1.2.0-beta.1 开始支持

Mobx 为复杂项目中状态管理提供了一种简单高效的机制;Taro 提供了 @tarojs/mobx 来让开发人员在使用Mobx的过程中获得更加良好的开发体验。

下文中示例代码均在 taro-mobx-sample

首先请安装 mobx@4.8.0@tarojs/mobx@tarojs/mobx-h5@tarojs/mobx-rn

  1. $ yarn add mobx@4.8.0 @tarojs/mobx @tarojs/mobx-h5 @tarojs/mobx-rn
  2. # 或者使用 npm
  3. $ npm install --save mobx@4.8.0 @tarojs/mobx @tarojs/mobx-h5 @tarojs/mobx-rn

随后可以在项目 src 目录下新增一个 store/counter.js 文件

  1. // src/store/counter.js
  2. import { observable } from 'mobx'
  3. const counterStore = observable({
  4. counter: 0,
  5. counterStore() {
  6. this.counter++
  7. },
  8. increment() {
  9. this.counter++
  10. },
  11. decrement() {
  12. this.counter--
  13. },
  14. incrementAsync() {
  15. setTimeout(() => {
  16. this.counter++
  17. }, 1000)
  18. }
  19. })
  20. export default counterStore

接下来在项目入口文件 app.js 中使用 @tarojs/mobx 中提供的 Provider 组件将前面写好的 store 接入应用中

  1. // src/app.js
  2. import Taro, { Component } from '@tarojs/taro'
  3. import { Provider } from '@tarojs/mobx'
  4. import Index from './pages/index'
  5. import counterStore from './store/counter'
  6. import './app.scss'
  7. const store = {
  8. counterStore
  9. }
  10. class App extends Component {
  11. config = {
  12. pages: [
  13. 'pages/index/index'
  14. ],
  15. window: {
  16. backgroundTextStyle: 'light',
  17. navigationBarBackgroundColor: '#fff',
  18. navigationBarTitleText: 'WeChat',
  19. navigationBarTextStyle: 'black'
  20. }
  21. }
  22. componentDidMount () {}
  23. componentDidShow () {}
  24. componentDidHide () {}
  25. componentDidCatchError () {}
  26. render () {
  27. return (
  28. <Provider store={store}>
  29. <Index />
  30. </Provider>
  31. )
  32. }
  33. }
  34. Taro.render(<App />, document.getElementById('app'))

然后,我们在页面中可通过 @tarojs/mobx 提供的 inject 以及 observer 方法将 mobx 与我们的页面进行关联

  1. // src/pages/index/index.js
  2. import Taro, { Component } from '@tarojs/taro'
  3. import { View, Button, Text } from '@tarojs/components'
  4. import { observer, inject } from '@tarojs/mobx'
  5. import './index.scss'
  6. @inject('counterStore')
  7. @observer
  8. class Index extends Component {
  9. config = {
  10. navigationBarTitleText: '首页'
  11. }
  12. componentWillMount () { }
  13. componentWillReact () {
  14. console.log('componentWillRect')
  15. }
  16. componentDidMount () { }
  17. componentWillUnmount () { }
  18. componentDidShow () { }
  19. componentDidHide () { }
  20. increment = () => {
  21. const { counterStore } = this.props
  22. counterStore.increment()
  23. }
  24. decrement = () => {
  25. const { counterStore } = this.props
  26. counterStore.decrement()
  27. }
  28. incrementAsync = () => {
  29. const { counterStore } = this.props
  30. counterStore.incrementAsync()
  31. }
  32. render () {
  33. const { counterStore: { counter } } = this.props
  34. return (
  35. <View className='index'>
  36. <Button onClick={this.increment}>+</Button>
  37. <Button onClick={this.decrement}>-</Button>
  38. <Button onClick={this.incrementAsync}>Add Async</Button>
  39. <Text>{counter}</Text>
  40. </View>
  41. )
  42. }
  43. }
  44. export default Index

上例中 Providerinjectobserver的使用方式基本上与mobx-react 保持了一致,但也有以下几点需要注意:

  • Provider不支持嵌套,即全局只能存在一个Provider
  • mobx-react中,可通过以下方式设置store

    1. <Provider store1={xxxx} store2={xxxx}>
    2. <XXX />
    3. </Provider>

    而在@tarojs/mobx中,我们需要使用以下方式设置:

    1. const store = {
    2. store1: xxxx,
    3. store2: xxxx
    4. }
    5. <Provider store={store}>
    6. <XXX />
    7. </Provider>
  • injectobserver 不能在stateless组件上使用

  • observer 不支持任何参数
  • 按照以下方式使用 inject 时,不能省略observer的显式调用:

    1. @inject((stores, props) => ({
    2. counterStore: stores.counterStore
    3. }))
    4. @observer //这个不能省略

注意事项:

  • Componentrender方法中,如果需要使用一个observable 对象(该例中为counter),您需要:

    1. const { counterStore: { counter } } = this.props
    2. return (
    3. <Text>{counter}</Text>
    4. )

    而非:

    1. const { counterStore } = this.props
    2. return (
    3. <Text>{counterStore.counter}</Text>
    4. )
  • 如果使用 @observable 装饰器来定义可观察对象时,请确保该属性已经初始化(这是很多情况下属性值改变,页面没刷新的根源所在),比如:

    1. @observable counter // 错误
    2. @observable counter = 0 // 正确
  • 1.2.0-beta.5后,propTypes已从taro-mobxtaro-mobx-h5taro-mobx-rn中剥离,如需使用,请单独进行安装:

    1. $ yarn add @tarojs/mobx-prop-types
    2. # 或者使用 npm
    3. $ npm install --save @tarojs/mobx-prop-types

    propTypes 使用与mobx-react 一致