guys. I`m working on ract+mobx+firebase app. I want to separate my app logic to 3 stores:
- authStore - store, where all firebase auth actions is happens
- userStore - where, stored all current user data, that came from firebase database
- edtorStore - all, stuff that happens in the editor component.
So to receive currentUser data from db , I firstly need to get the currentUser.uid from fb.auth(). My AuthStore look like this:
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 };
My 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 };
All my stores I import to one global store
import { authStore } from './AuthStore';
import { user } from './CurrentUser'
import { editor } from './EditorStore'
const store = {
authStore,
user,
editor
};
window.store = store;
export { store };
And then import this store where they need.
Now I have some questions:
How I can set my
userStore.userinuserStoreconstructor, if I need receivecurrentUser.uidfrom authStore? Ive tried to import **authStore** to **userStore** and versa, but it didnt help, because both watchers (authStatusChange and userRef.on(‘value’) must be placed at the store constructor (am I right?). And because I create an instance of storeClass at the beginning – they instantiated beforeauth.currentUserget positive response from server. I solve this issue, by inserting authStatusChange watcher in both stores, but I think it’s not good solutionIn my app some components can be displayed only when userStore.user exist, and if I not make user @observable – I can check by
if(user)…, but because his observableif(user)return true – because his return observable object. How I can check if user already settedUp or not?User in db have field – project. Project is the deeply nested object, that I use to describe the user project structure and display on the front. When user enter to the Editor – editor component split this project to the blocks. Every block have his style property, that user can edit. So when user select some block, this block is writted in the editorStore as currentBlock observable object, by using @action setCurrentBlock, and as argument receive the reference to the selected block.
class EditorStore { @observable currentBlock = null;
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; }}
const editor = new EditorStore (); export { editor };
So my editStylesPanel component is displaying the current block styles value that came from @computed blockStyles. Everything is fine, but when I change some style property through @action updateBlockStyle – his update only the styles of editorStore.currentBlock, and does not change the style in the relevant block of user.project. I was sure that if I send a reference to the object –as any changes in t editorStore must be happens on the root object. Why is this not happen?
- And the last questions – what is the better way to inject stores to the components?
Through
<Provider store={…stores}>and@inject(‘store’)Or byimport {store} from ‘./store/store’
Thanks for you help ;)