如何在Mobx状态树中使用来自不同状态的动作

时间:2019-02-12 13:44:40

标签: typescript mobx mobx-state-tree

我创建了两个Mobx状态树状态:Ui和数据。

UI.ts:

export const UI = t
  .model('UI', {
    widthPage: t.optional(t.number, 0),
    heightPage: t.optional(t.number, 0),
  })
  .views(self => ({
    get activeCategory() {
      // here I need to do some operation on values attribute of Data store
    },
  }))
  .actions(self => ({
  }))

和Data.ts:

import { types as t } from 'mobx-state-tree'
import {
  ValueType,
} from '../lib/types'
const values = require('../dataset/normalized/values.csv')

export const Data = t
  .model('Data', {
    values: t.optional(t.frozen<ValueType[]>(), values),
  })
  .views(self => ({
    getSomething(country: string): number {
      return 5
    },
  }))
  .actions(self => ({
  }))

然后我还有文件index.ts和main.tsx。

index.ts:

export const State = t
  .model('State', {
    ui: t.optional(UI, {}),
    data: t.optional(Data, {}),
  })
  .views(self => ({}))
  .actions(self => ({
    resetSubState(subState: typeof self.ui | typeof self.data) {
      const subStateName = subState.$treenode.subpath
      self[subStateName] = {}
    },
  }))

export type StateType = typeof State.Type

export interface IStateable {
  state?: StateType
}

main.tsx:

const state = State.create({})

如何从UI状态使用数据状态操作,反之亦然? 我看到了方法getEnv,但我不知道如何使用...

2 个答案:

答案 0 :(得分:0)

最简单的方法是让activeCategory的调用者将Data中的数据传递到视图中。

这意味着虽然不使用计算属性:

getActiveCategory(dataStore.whateverPropIsNeeded, ...)

如果这些存储区不是同一棵树的一部分,则getEnv不会太糟糕(在您的示例中,它们是同一棵树的一部分)。.

const DataStore = Data.create({});
const UIStore = UI.create({}, { dataStore });

然后在UIStore中可以完成

const dataStore = getEnv(self).dataStore;

如果它们是同一棵树的一部分,则getEnv并不是一个好方法,因为MST有一个约束,即树中的所有节点必须具有相同的依赖项(由getEnv返回的相同对象)。

或者,数据可以是UI的子级。尽管在大多数情况下,我都不喜欢这种方法。

最后一个解决方案...这两个存储的父级可以公开使用UI和数据的视图。但是,这可能会导致模型膨胀。.这些解决方案都不是完美的,因此我很想知道还会弹出其他答案。

答案 1 :(得分:0)

getEnv()是一种从MST中的任何节点访问某些环境变量(您先前传递到根节点的 )的一种方法,无论深度如何(React中的 Think Context) )。

  

创建新的状态树时,可以传入环境   通过将对象作为第二个参数传递给.create来获得特定数据   呼叫。该对象应(浅)不可变,并且可以访问   树中的任何模型通过调用getEnv(self)来实现。这对   注入环境或特定于测试的实用程序,例如传输层,   记录器等。

非常方便,但似乎不是您所需要的。

有许多种遍历MST的方法。例如,您可以将unique identifier分配给任何节点,然后可以从MST中的任何其他节点检索它。

您还可以使用getRoot(self)getParent(self, depth=1)getParentOfType(self, type)助手来从给定节点向上遍历树。

但是在您的情况下,最简单的方法是使用resolvePath(node, path)。因此,基本上,从data中的任何视图或操作中,您都可以做到:

import { types as t, resolvePath } from 'mobx-state-tree'

// ...

resolvePath(self, '../ui').activeCategory