MobX,以及商店之间的连接

Eug*_*itz 5 javascript firebase reactjs mobx mobx-react

伙计们。\n我正在开发 ract+mobx+firebase 应用程序。\n我想将我的应用程序逻辑分为 3 个商店:

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

因此,要从 db 接收 currentUser 数据,我首先需要从fb.auth()获取currentUser.uid。\n我的AuthStore如下所示:

\n\n
class AuthStore {\n    @observable auth = {\n        authUser  : null,\n        authError : null\n    };\n\n    constructor () {\n        console.log ( \'start auth\' );\n        this.unwatchAuth = Fb.auth.onAuthStateChanged ( user => {\n            console.log ( \'status changed\' );\n            this.auth.authUser = user;\n        } );\n    }\n\n    @computed\n    get currentUser () {\n        console.log ( \'updated\' );\n        return this.auth.authUser;\n    }\n}\n\nconst authStore = new AuthStore ();\nexport { authStore };\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的用户存储

\n\n
class CurrentUser {\n    @observable user = ( {} );\n    constructor () {\n            this.userRef       = Fb.dbRoot.ref ( `users/${user.uid}` );\n            this.userRef.on ( \'value\', ( snapshot ) => {\n                this.user = snapshot.val ();\n            } );\n        } );\n    }\n}\n\nconst user = new CurrentUser ();\nexport { user };\n
Run Code Online (Sandbox Code Playgroud)\n\n

我将所有商店导入到一家全球商店

\n\n
import { authStore } from \'./AuthStore\';\nimport { user } from \'./CurrentUser\'\nimport { editor } from \'./EditorStore\'\n\nconst store = {\n    authStore,\n    user,\n    editor\n};\n\nwindow.store = store;\n\nexport { store };\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在他们需要的地方导入这个商店。

\n\n

现在我有一些问题:

\n\n
    \n
  1. 如果我需要\n从 authStore 接收,我如何在构造函数userStore.user中设置?\n这没有帮助,因为两个观察者(authStatusChangeuserRef.on(\xe2\x80\x98value\xe2\x80\x99)必须放置在存储构造函数中(我对吗?)。 \n因为我创建了一个实例storeClass在 \xe2\x80\x93 开头,它们在得到服务器的肯定响应之前实例化。我通过在两个商店中插入authStatusChange观察器解决了这个问题,但我认为 \xe2\x80\x99s 不是一个好的解决方案userStorecurrentUser.uidve tried to import **authStore** to **userStore** and versa, but it didnauth.currentUser

  2. \n
  3. 在我的应用程序中,只有当userStore.user存在时才能显示某些组件,如果我不让用户 @observable \xe2\x80\x93 我可以通过 , \n 检查if(user)\xe2\x80\xa6, \nbut 因为他的可观察if(user)返回 true \xe2\x80\x93 因为他的返回可观察的物体。我如何检查用户是否已经设置?

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

    \n\n

    类 EditorStore {\n @observable currentBlock = null;

    \n\n
    constructor () {\n}\n\n@computed\nget blockStyles () {\n    return this.currentBlock.style\n}\n\n@action\nsetCurrentBlock ( block ) {\n    this.currentBlock = block\n}\n\n@action\nupdateBlockStyle ( data ) {\n    const { styleProp, value }           = data;\n    this.currentBlock.style[ styleProp ] = value;\n}\n
    Run Code Online (Sandbox Code Playgroud)\n\n

    }

    \n\n

    const editor = new EditorStore ();\nexport { editor };

  6. \n
\n\n

因此,我的editStylesPanel组件显示来自@compulated blockStyles 的当前块样式值。\n一切都很好,但是当我通过@action updateBlockStyle \xe2\x80\x93更改某些样式属性时,他仅更新editorStore.currentBlock的样式,并且不会更改user.project相关块中的样式。\n我确定如果我发送对对象 \xe2\x80\x93 的引用,则 t editorStore 中的任何更改都必须发生在根对象上。\n为什么不会发生这种情况?

\n\n
    \n
  1. 最后一个问题 \xe2\x80\x93 将存储注入组件的更好方法是什么?\n通过<Provider store={\xe2\x80\xa6stores}>@inject(\xe2\x80\x98store\xe2\x80\x99)\n或通过import {store} from \xe2\x80\x98./store/store\xe2\x80\x99
  2. \n
\n\n

感谢您的帮助;)

\n

Fak*_*ish 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
    ...
}
Run Code Online (Sandbox Code Playgroud)

虽然它有效,但我希望有更好的解决方案。也许就是这个