MobX和商店之间的连接

时间:2017-06-09 07:00:39

标签: javascript reactjs firebase mobx mobx-react

人。 我正在开发ract + mobx + firebase app。 我想将我的app逻辑分成3个商店:

  • authStore - 存储,其中所有firebase身份验证操作都已发生
  • userStore - 其中存储了来自firebase数据库的所有当前用户数据
  • edtorStore - 编辑器组件中发生的所有内容。

因此,要从db接收currentUser数据,我首先需要从 fb.auth()获取 currentUser.uid 。 我的 AuthStore 看起来像这样:

class AuthStore {
    @observable auth = {
        authUser  : null,
        authError : null
    };

    constructor () {
        console.log ( 'start auth' );
        this.unwatchAuth = Fb.auth.onAuthStateChanged ( user => {
            console.log ( 'status changed' );
            this.auth.authUser = user;
        } );
    }

    @computed
    get currentUser () {
        console.log ( 'updated' );
        return this.auth.authUser;
    }
}

const authStore = new AuthStore ();
export { authStore };

我的 UserStore

class CurrentUser {
    @observable user = ( {} );
    constructor () {
            this.userRef       = Fb.dbRoot.ref ( `users/${user.uid}` );
            this.userRef.on ( 'value', ( snapshot ) => {
                this.user = snapshot.val ();
            } );
        } );
    }
}

const user = new CurrentUser ();
export { user };

我导入一家全球商店的所有商店

import { authStore } from './AuthStore';
import { user } from './CurrentUser'
import { editor } from './EditorStore'

const store = {
    authStore,
    user,
    editor
};

window.store = store;

export { store };

然后将该商店导入他们需要的地方。

现在我有一些问题:

  1. 如果需要,如何在userStore.user构造函数中设置userStore 从authStore收到currentUser.uid? 我ve tried to import **authStore** to **userStore** and versa, but it didn提供帮助,因为必须将两位观察者( authStatusChange userRef.on('value')放在商店构造函数中(我是对的吗?) 。 因为我在开头创建了 storeClass 的实例 - 它们在auth.currentUser获得服务器肯定响应之前实例化。我通过在两个商店中插入 authStatusChange 观察者来解决这个问题,但我认为这不是一个好的解决方案

  2. 在我的应用中,某些组件只有在 userStore.user 存在时才能显示,如果我没有用户@observable - 我可以通过{{查看1}}, 但是因为他的可观察if(user)…返回真实 - 因为他的回归是可观察的对象。我如何检查用户是否已经设置了?

  3. db中的用户有字段 - 项目。 Project是深度嵌套的对象,我用它来描述用户项目结构并在前面显示。 当用户进入编辑器时 - 编辑器组件将此项目拆分为块。 每个块都有自己的样式属性,用户可以编辑。 因此,当用户选择某个块时,此块将作为 currentBlock 可观察对象在 editorStore 中写入,使用 @action setCurrentBlock ,并作为参数接收对所选块的引用。

    类EditorStore {     @observable currentBlock = null;

    if(user)

    }

    const editor = new EditorStore(); export {editor};

  4. 所以我的 editStylesPanel 组件显示来自 @computed blockStyles 的当前块样式值。 一切都很好,但是当我通过 @action updateBlockStyle 更改一些样式属性时 - 他只更新 editorStore.currentBlock 的样式,并且不会更改相关块中的样式 user.project 。 我确信如果我发送对该对象的引用 - 那么必须在根对象上发生t editorStore的任何更改。 为什么这不会发生?

    1. 最后一个问题 - 将商店注入组件的更好方法是什么? 通过constructor () { } @computed get blockStyles () { return this.currentBlock.style } @action setCurrentBlock ( block ) { this.currentBlock = block } @action updateBlockStyle ( data ) { const { styleProp, value } = data; this.currentBlock.style[ styleProp ] = value; } <Provider store={…stores}> 或者@inject(‘store’)
    2. 谢谢你的帮助;)

2 个答案:

答案 0 :(得分:1)

这是我在相同情况下所做的:

// src/stores/index.js

import {RouterStore} from 'mobx-router5';
import AuthStore from './AuthStore';

const stores = {};

const routerStore = new RouterStore(stores); // Provide access to other stores
const authStore = new AuthStore(stores);

stores.routerStore = routerStore;
stores.authStore = authStore;

export default stores;


// src/stores/AuthStore.js

export default class AuthStore {
    ...
    constructor(stores) {this.stores = stores}; // Keep stores reference for later
    ...
}

尽管可以,但我希望有更好的解决方案。也许this one

答案 1 :(得分:0)

您可以在 global 对象中保存您商店的引用


export const storesLoader = () => {
  const stores = {
    routerStore: new RouterStore(),
    authStore = new AuthStore()
  };

  if (global && typeof global.stores != 'object') {
    global.stores = stores;
  }
}

然后通过全局对象本身访问商店。

  • 但请记住,如果您想更改另一个商店中商店的可观察对象,请为其定义一个操作。否则,您的新值不会触发 Mobx 观察者。