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, onError } 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. onError(error => {
    11. console.log('mobx global error listener:', error)
    12. })
    13. class App extends Component {
    14. config = {
    15. pages: [
    16. 'pages/index/index'
    17. ],
    18. window: {
    19. backgroundTextStyle: 'light',
    20. navigationBarBackgroundColor: '#fff',
    21. navigationBarTitleText: 'WeChat',
    22. navigationBarTextStyle: 'black'
    23. }
    24. }
    25. componentDidMount () {}
    26. componentDidShow () {}
    27. componentDidHide () {}
    28. componentDidCatchError () {}
    29. render () {
    30. return (
    31. <Provider store={store}>
    32. <Index />
    33. </Provider>
    34. )
    35. }
    36. }
    37. 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. console.log('componentWillMount')
    14. }
    15. /**
    16. * 该方法将在 observable 对象更新时触发
    17. */
    18. componentWillReact () {
    19. console.log('componentWillReact')
    20. }
    21. componentDidMount () {
    22. console.log('componentDidMount')
    23. }
    24. componentWillUnmount () {
    25. console.log('componentWillUnmount')
    26. }
    27. componentDidShow () {
    28. console.log('componentDidShow')
    29. }
    30. componentDidHide () {
    31. console.log('componentDidHide')
    32. }
    33. increment = () => {
    34. const { counterStore } = this.props
    35. counterStore.increment()
    36. }
    37. decrement = () => {
    38. const { counterStore } = this.props
    39. counterStore.decrement()
    40. }
    41. incrementAsync = () => {
    42. const { counterStore } = this.props
    43. counterStore.incrementAsync()
    44. }
    45. render () {
    46. const { counterStore: { counter } } = this.props
    47. return (
    48. <View className='index'>
    49. <Button onClick={this.increment}>+</Button>
    50. <Button onClick={this.decrement}>-</Button>
    51. <Button onClick={this.incrementAsync}>Add Async</Button>
    52. <Text>{counter}</Text>
    53. </View>
    54. )
    55. }
    56. }
    57. export default Index

    上例中 ProviderinjectobserveronError 的使用方式基本上与 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 一致

    注:自 1.2.27-beta.0 后,@tarojs/mobx-prop-types 已被移除,请使用 mobx-react 替代。