Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Split Mobx State Tree Models Across Multiple Files?

I have a Mobx State Tree model that has grown too long and I would like to split it across multiple javascript files.

Here is a demo of some of the code:

///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
    }
}))

What I want is to split this between two files, like:

///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
    }
}))

You can see here that I am attempting to move a view and and action to a separate javascript file. I expect I need to do some kind of import and export between these two files, but I can't figure out how to do it.

I know that Mobx State Tree has compose functionality, as shown here: https://nathanbirrell.me/notes/composition-mobx-state-tree/

But I am afer something more simple than this... I don't want to set up multiple models, I just need the ability to spread a model across multiple javascript files.

like image 532
Alexander Perls Avatar asked Jan 02 '23 11:01

Alexander Perls


1 Answers

We do that all the time.

Just export your actions and views separately:

// 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
    }
})

Then, create the final store from them:

// 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

You can also create your own stores for testing, only from one file:

// __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')
})
like image 93
Luis Herranz Avatar answered Mar 19 '23 07:03

Luis Herranz