In MobX, accessing another store from within a store can be achieved through several methods. Here are some common approaches:
1. Dependency Injection via Constructor
When creating a store instance, pass other required stores as parameters. This approach is similar to dependency injection, allowing each store to have references to other stores during initialization.
javascriptclass StoreA { constructor(storeB) { this.storeB = storeB; } get someData() { return this.storeB.someOtherData; } } class StoreB { someOtherData = "This is some data from StoreB"; } const storeB = new StoreB(); const storeA = new StoreA(storeB);
In the above example, StoreA receives an instance of StoreB as a parameter during its creation and stores it in its own property. This allows StoreA to easily access data from StoreB.
2. Root Store Pattern
The Root Store pattern involves creating a main store, typically called RootStore, which holds references to all other child stores. Then, each child store can receive the RootStore instance as a parameter in its constructor and access other stores through it.
javascriptclass StoreA { constructor(rootStore) { this.rootStore = rootStore; } get someData() { return this.rootStore.storeB.someOtherData; } } class StoreB { someOtherData = "This is some data from StoreB"; } class RootStore { constructor() { this.storeB = new StoreB(); this.storeA = new StoreA(this); } } const rootStore = new RootStore();
With this approach, all stores are connected through the RootStore, and each store can access other store instances within the root store.
3. Using MobX's context
When using React and MobX, leverage React's context system to pass stores. This is particularly useful for accessing stores within the React component tree.
javascriptimport React, { createContext, useContext } from 'react'; import { useLocalObservable } from 'mobx-react'; const StoreContext = createContext(null); export const StoreProvider = ({ children }) => { const store = useLocalObservable(() => ({ storeA: new StoreA(), storeB: new StoreB(), })); return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>; }; export const useStores = () => useContext(StoreContext);
In components, use the useStores hook to access storeA and storeB:
javascriptconst MyComponent = () => { const { storeA, storeB } = useStores(); // Use storeA and storeB };
These methods provide ways to access stores across different stores, each with its own use cases and trade-offs. Dependency Injection via Constructor and Root Store Pattern are better suited for non-React or large React projects, while the context method is designed specifically for React. In actual projects, choose the appropriate method based on your architectural requirements and team preferences.
In MobX, there are several ways to access another store from within a store. The following are common approaches:
1. Dependency Injection via Constructor
A simple and direct method is to pass other stores as parameters when creating a store. For example:
javascriptclass StoreA { constructor(storeB) { this.storeB = storeB; } } class StoreB { // StoreB methods and properties } const storeB = new StoreB(); const storeA = new StoreA(storeB);
The benefit is clear dependency declaration and ease of testing, as you can easily pass mocks or stubs.
2. Using Root Store Pattern
Typically, in larger applications, you have a "root" store that holds instances of all other child stores. This way, each child store can access other stores through the root store.
javascriptclass RootStore { constructor() { this.storeA = new StoreA(this); this.storeB = new StoreB(this); } } class StoreA { constructor(rootStore) { this.rootStore = rootStore; } someMethod() { // Access StoreB's methods or properties directly through the root store return this.rootStore.storeB.someProperty; } } class StoreB { // StoreB methods and properties } const rootStore = new RootStore();
The benefit is that each store knows how to find any other store it needs without additional references or configuration.
3. Using MobX's context (in React environment)
If your application is developed with React and you're using MobX for state management, leverage React's Context API to pass stores across components.
javascriptimport React, { createContext, useContext } from 'react'; const StoreContext = createContext(); const StoreProvider = ({ children, store }) => { return ( <StoreContext.Provider value={store}>{children} </StoreContext.Provider> ); }; // Custom hook to access store const useStores = () => useContext(StoreContext); // Usage in components const MyComponent = () => { const { storeA, storeB } = useStores(); // ... };
In this case, wrap your component tree with a StoreProvider at the top of your application, and access stores anywhere using the useStores custom hook.
4. Using Global Variables or Modules
Although generally not recommended, in simple applications or quick prototypes, you might choose to expose stores as global variables or export them as part of a module, as shown below:
javascript// stores.js export const storeA = new StoreA(); export const storeB = new StoreB(storeA);
Then import them where needed:
javascriptimport { storeA, storeB } from './stores'; // Use storeB's methods or properties storeA.someMethod(storeB.someProperty);
This method is simple and quick, but in large applications, it can lead to hard-to-maintain code and unclear dependencies.
The above are several ways to enable stores to access each other in MobX. Choose the appropriate method based on your application's specific requirements and structure.