使用mobx-react 的inject 装饰器 与 不用的区别?

#1

使用mobx过程中,如果store我是这么写的:

import fetch from './fetch.js'
import load from './load.js'
const stores = {fetch ,load }
export default  stores

在实际的组件中,将需要用到的store 可以使用@inject 直接注入组件,然后直接在this.props.xxx 这么获取就行了。这好像是比较标准的做法。

那如果不用的@inject的话,也有看到过别人写的代码,不会将多个小store 放到store 文件中,而是在需要用到store的组件中直接:

import load from './load.js'
// 不在load.js 中new 了
const loadStore = new Load()

 ...

<li>{loadStore.xxx.a}</li>
...

或者也有人说可以将所有的store都在根组件中通过props传递下来,太深就用context。

不过这三种方式确实是使用@inject 直接按需注入方便很多,数据更加明确吧。但是我想问一下这三种形式,除了方便之外还有什么区别?

#2

用了provider在用inject。
这是官方推荐的用法。
http://react-china.org/t/mobx4-react16-react-router4-ant-design3/19622看一下具体用法

#3

看了你的代码,有几个不是很明白的地方,想问一问有些用法上你是如何思考的:

  1. 为什么在有全局的store之后,我们还需要对应login 组件还需要单独的store?可能是我写的react 还太少不是很明白为什么单独的store是写在组件里面的? 如果将login 的store 也写成另一个全局的store,并在最外层的provider 就渗透下去,我尝试了一下这么写,好像可以也是可以的,不知道这样的写法跟你这种的区别在哪里?
/* ========================================================

    ** Login自己的store **

    不要直接实例化,在 container 通过 Provider 渗透到所有子组件。
    在子组件内用 @inject('store'),将 store 注入到自己的 props 上。

   ====================================================== */
import { observable, action } from 'mobx'

class Store {
  @observable loading = false
  @action updateLoading = (boolean) => {
    this.loading = boolean
  }
}

export default Store
  1. 同样是上面的login store ,我不太理解的是为什么我们必须每一次都在初始化的时候new ?我理解login组件的constructer也就只会执行一次(登录页不会反复进入),那其实放在new store() 跟new store()之后export 再import 好像没啥区别?
class Login extends Component {
  constructor() {
    super()
    this.store = new store() // 在这里实例化,保证每次加载组件数据的初始化。
  }
...

emmm 可能我的问题在大佬看来很简单,不过还是希望大佬能够解一下我的惑,:wink:

#4

:sweat_smile:你的思考正好和我当时相反。
一:我第一次用mobx时就是直接new出来,这时无论你的组件怎么卸载加载,store都不会初始化。
假如你有一个需求在某一个view里点按钮有一个弹框出现(很常见吧),这个弹框的显示隐藏由mobx控制,当弹框显示时跳转路由到另一个组件再跳回来,此时弹框不会消失。
按正常操作习惯来讲,切换出去再回来是要刷新的,除非你要做keep-alive。
二:想一下如果是多人协作的项目,所有人都维护同一个全局store那该有多恐怖。还有这些状态管理器存在的意义仅仅是为了一个全局store?显然不是。
三:两个模块内的store都是用法示例。provider配合inject是我个人觉得比较规范实用的用法,未来context出了新api,这种方式可能还要改变。

#5

你说的页面跳转弹框不会消失的问题确实存在,当然我之前是通过在组件的constructer中触发一个action 来reset store的值解决弹框不会消失的问题。不过感觉在constructer中 new 一个store的做法有点好~

然后,其实我说的再创建一个store的形式,像是这样的:


import deviceStore from './deviceStore'
import loginStore from './loginStore'
import delModalStore from './device/DelModalStore'
import editModalStore from './device/EditModalStore'

const stores = {
  deviceStore,
  loginStore,
  delModalStore,
  editModalStore
}

export default stores

目前我在多人协作的时候,肯定是各自创建store,然后都放到全局的stores 中,再在根组件中,用provider配合inject只要一次就行了。我想了一下,其实创建组件自身的store 效果其实跟state 一样啊。。

#6

请问跳转到另外个界面,store如何做到跟着界面componentWillUnmount自动释放?