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

问题描述 投票:1回答:2

我创建了两个Mobx State Tree状态:Ui和Data。

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状态使用Data状态的操作,反之亦然?我看到了方法getEnv但我不知道如何使用它...

typescript mobx mobx-state-tree
2个回答
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返回相同的对象)。

或者,Data可以是UI的子级。对于大多数用例,我并不喜欢这种方法。

最后一个解决方案......这两个商店的父级可以公开同时使用UI和数据的视图。可能会导致一个臃肿的模型..这些解决方案都不是完美的所以我很想看到其他答案弹出。


0
投票

getEnv()是一种从MST中的任何节点访问一些环境变量(您之前传递给根节点)的方法,无论深度如何(想想React中的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
© www.soinside.com 2019 - 2024. All rights reserved.