【问题标题】:Recommended way for observing UI window from within a mobx-state-tree store从 mobx-state-tree 存储中观察 UI 窗口的推荐方法
【发布时间】:2018-03-25 20:18:58
【问题描述】:

我在玩 mobx-state-tree 并试图找出将 window.innerHeight 之类的东西绑定到我的商店的最佳方法。我对Mobx 完全陌生,所以我无法立即想象如何使用observer()(或其他相关方法)来集成它。在docs 中纯粹使用Mobx 似乎有一些很好的信息,但我想知道mobx-state-tree 的推荐内容。

据我所知,我可以从使用getEnv() 获取window 开始,遵循dependency injection 的文档:

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 存储的子节点?

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

【问题讨论】:

    标签: user-interface mobx observers mobx-react mobx-state-tree


    【解决方案1】:

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

    来自mobx-state-treedocs,它提到了[我添加的重点]:

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

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

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

    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兼容。]

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

    【讨论】:

      猜你喜欢
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 2017-06-27
      • 1970-01-01
      相关资源
      最近更新 更多