1

我正在玩mobx-state-tree,我正在尝试找出最好的方法来让像window.innerHeight被绑在我的商店里这样的东西。我对 完全陌生Mobx,所以我无法立即想象如何使用observer()(或其他相关方法)集成它。似乎有一些很好的信息可以Mobx文档中纯粹使用,但我想知道推荐用于什么mobx-state-tree

根据我的猜测,我可以从windowusing开始,遵循依赖注入getEnv()的文档:

Example.js

import { types, getEnv } from "mobx-state-tree"

const Box = types.model({
        width: types.number,
        height: types.number
    })
    .actions(self => ({
        setWidth() {
            const width = getEnv(self).window.innerWidth
            self.width = width / 10
        }
    }))

export default Box

测试文件

import {Box} from './Example'

//mock window for testing
const window = {
    innerWidth: 1200
}

const store = Box.create({
        width: 100,
        height: 100
    }, {
        window: window /* inject window into store */
    }
)

//Test
it('updates from window width', () => {
  store.setWidth()
  expect(store.width).toBe(120)
})

这在我在测试套件中运行时有效。

我将如何写这个以便任何时候window.innerWidth改变Box都会重新计算它的宽度?也许我可以使用views, 并且已经Box成为代表更改的更大 UI 存储的子节点?

任何建议将不胜感激,并提前致谢!

4

1 回答 1

1

也许最好的解决方案是将其包含在mobx-state-tree并使用单独的mobx商店。

mobx-state-tree docs中,它提到[强调由我添加]:

我的应用程序的所有状态都应该存储在 mobx-state-tree 中吗?

不,或者,不一定。应用程序可以同时使用状态树和普通的 MobX 可观察对象。状态树主要用于存储您的域数据,因为这种状态通常是分布式的并且不是非常本地化的。例如,对于本地组件状态,普通的 MobX 可观察对象可能通常更易于使用。

这意味着人们可以使用类似mobx 文档中的示例:

import {observable, computed, asStructure} from 'mobx';
import jquery from 'jquery';

export class UiState {
    @observable language = "en_US";
    @observable pendingRequestCount = 0;

    // .struct makes sure observer won't be signaled unless the
    // dimensions object changed in a deepEqual manner
    @observable.struct windowDimensions = {
        width: jquery(window).width(),
        height: jquery(window).height()
    };

    constructor() {
        jquery.resize(() => {
            this.windowDimensions = getWindowDimensions();
        });
    }

    @computed get appIsInSync() {
        return this.pendingRequestCount === 0
    }
}

[注意:需要通过删除装饰器语法来修改它以使其与create-react-app.]

是为窗口大小构建商店的完整示例。

于 2018-03-25T20:18:58.803 回答