如何跨多个文件拆分 Mobx 状态树模型?

How To Split Mobx State Tree Models Across Multiple Files?

我有一个 Mobx 状态树模型已经变得太长了,我想将它拆分成多个 javascript 个文件。

下面是一些代码的演示:

///file1.js
 import { types } from "mobx-state-tree";

export const ExampleModel = types
.model("Example", {
    id: types.identifier,
    name: types.optional(types.string, ""),
    anotherName: types.optional(types.string, ""),

})
.views(self => ({
    get test() {
        return "test"
    }
}))
.views(self => ({
    get anotherTest() {
        return "anotherTest"
    }
}))
.actions(self => ({
    setName(name) {
        self.name = name
    }
}))
.actions(self => ({
    setAnotherName(name) {
        self.anotherName = name
    }
}))

我想要的是将其拆分为两个文件,例如:

///file1.js
import { types } from "mobx-state-tree";

export const ExampleModel = types
.model("Example", {
    id: types.identifier,
    name: types.optional(types.string, ""),
    anotherName: types.optional(types.string, ""),

})
.views(self => ({
    get test() {
        return "test"
    }
})) 
.actions(self => ({
    setName(name) {
        self.name = name
    }
}))


///file2.js
import { ExampleModel } from "./file1.js";
ExampleModel.views(self => ({
    get anotherTest() {
        return "anotherTest"
    }
})).actions(self => ({
    setAnotherName(name) {
        self.anotherName = name
    }
}))

您可以在此处看到我正在尝试将视图和操作移动到单独的 javascript 文件中。我希望我需要在这两个文件之间进行某种导入和导出,但我不知道该怎么做。

我知道 Mobx State Tree 具有组合功能,如下所示: https://nathanbirrell.me/notes/composition-mobx-state-tree/

但我想要比这更简单的东西...我不想设置多个模型,我只需要能够跨多个 javascript 文件传播一个模型。

我们一直这样做。

只需分别导出您的操作和视图:

// file1.js
import { types } from "mobx-state-tree"

export const props = {
    id: types.identifier,
    name: types.optional(types.string, ""),
    anotherName: types.optional(types.string, ""),

}
export const views = self => ({
    get test() {
        return "test"
    }
})
export const actions = self => ({
    setName(name) {
        self.name = name
    }
})

然后,根据它们创建最终商店:

// store.js
import { types } from "mobx-state-tree"
import * as file1 from "./file1"
import * as file2 from "./file2"

const Store = types
  .model('Store')
  .props(file1.props)
  .views(file1.views)
  .actions(file1.actions)
  .props(file2.props)
  .views(file2.views)
  .actions(file2.actions)

export default Store

您也可以只从一个文件创建自己的商店进行测试:

// __tests__/file1.js
import { types } from "mobx-state-tree"
import { actions, views, props } from "./file1"

const Store = types
  .model('Store')
  .props(props)
  .views(views)
  .actions(actions)
const store = Store.create(myTestSnapshot)

test('setName should set the name prop', () => {
  store.setName('john')
  expect(store.name).toBe('john')
})

富有表现力、灵活和简单的模型组合是 mobx-state-tree 中最好的功能之一! :) 这里有两个例子,直接取自 the relevant section in the docs:

const Square = types
    .model("Square", {
        width: types.number
    })
    .views(self => ({
        surface() {
            return self.width * self.width
        }
    }))

// create a new type, based on Square
const Box = Square
    .named("Box")
    .views(self => {
        // save the base implementation of surface
        const superSurface = self.surface
        return {
            // super contrived override example!
            surface() {
                return superSurface() * 1
            },
            volume() {
                return self.surface * self.width
            }
        }
    }))

// no inheritance, but, union types and code reuse
const Shape = types.union(Box, Square)

还有一个:

const CreationLogger = types.model().actions(self => ({
    afterCreate() {
        console.log("Instantiated " + getType(self).name)
    }
}))

const BaseSquare = types
    .model({
        width: types.number
    })
    .views(self => ({
        surface() {
            return self.width * self.width
        }
    }))

export const LoggingSquare = types
    .compose(
        // combine a simple square model...
        BaseSquare,
        // ... with the logger type
        CreationLogger
    )
    // ..and give it a nice name
    .named("LoggingSquare")

将其应用于您的需要:SquareBox 可以在不同的文件中,其中 Box.js 在第一个示例中从 Square.js 导入 Square .

可以对第二个示例应用完全相同的技术。