-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Importing store directly or pass as props? #300
Comments
In general there are three ways in which you can pass stores in MobX
Your current solution is a combination of |
I agree |
Or use a DI solution like InversifyJS as we use in https://github.com/Mercateo/dwatch. It is currently for us the best way which works with any framework and is useful for mocks in unit tests. |
@flipjs this is a good example of what you're setting out to accomplish: ContextProvider & connect function |
@evankline For my use case, a simple decorator is enough to inject the whole store (or a subset of it) to the component. MobX is not redux where injecting the whole store has perfomance implications where it will re-render every time a part of store has changed. Thats why redux uses mapStateToProps to inject only what the component needs. |
how to konw the store had changed? I think
|
@stephenkingsley although context is indeed an experimental feature, I wouldn't be afraid to use. Many core libraries in react land, like router and redux, depend on it, so I cannot imagine that it would be removed without offering a clear alternative. With MobX you don't need to know that the store has changed; any stuff from the store that is used in the render will be reacted to. If all data is observable, you simply cannot under (or over) subscribe. For the same reason there is no performance penalty if you pass stores which are not actually used. |
If data in store had changed, the component that is used |
Eh yeah..., doing that is basically the whole point of MobX :) |
See also: mobxjs/mobx-react#53 |
See pull request #65 , build |
@mweststrate that just the same i create last night. I also create a provide and connect |
|
Cool stuff! Will try it out. Thanks @mweststrate ! |
@mweststrate how do you unit-test a component that observes usinh this mechanism? It throws an error since it expects one of its ancestors to be wrapped with 'provider', but I'm rendering only it directly in the test |
@liady wrapping with provider is not required if all requested stores are passed in as normal props to the injected component. |
@mweststrate sorry, I was unclear in my question.. Hope I can clarify. |
@liady manually providing a prop
|
@liady most test examples i met manually pass store as props. It will ensure that component works properly without any concern about his environment |
Can some one link any example of using Provider? i got strange error while implementing |
Pass only one component into it. Wrap with a div for example if needed Op zo 28 aug. 2016 00:10 schreef Pavel Poberezhnyi <notifications@github.com
|
thanks for such rapid solution! i'm very happy with this approach |
I'm using React Router, which supports supplying a custom I also have a class TodoStore {
@observable todos = []
constructor({ root }) {
this.root = root
}
@computed todosForUser() {
// Reference state from another store.
const user = this.root.sessionStore.currentUser
return this.todos.filter(todo => todo.userId === user.id)
}
}
class SessionStore {
@observable currentUser
constructor({ root }) {
this.root = root
}
}
class RootStore {
constructor() {
this.todoStore = new TodoStore({ root: this })
this.sessionStore = new SessionStore({ root: this })
}
} In React Router: // Singleton, same instance used for the lifetime of the app
const rootStore = new RootStore()
const createElement = (Element, props) => <Element rootStore={rootStore} {...props})
const AppRouter = () => (
<Router createElement={createElement}>
...
</Router>
) Now my root store is passed into my screen components as props. |
You could also use context to pass the store to deeply nested components. |
I seem remember there is a |
@KaySackey @stepenhingsley yep see |
@mweststrate As per your comment on Jun3rd three approaches for using Stores .Can you suggest the best practice ? and Share few examples how to use them in that approach . |
Hi @mweststrate Just finally getting around to experimenting with mobX in a project. Similar to @Kamaraju333's request, I think that making note of practices regarding store importing / passing stores around in React in the docs would be pretty cool :) I might have missed something when reading through the docs, but I also have found myself a little anxious wondering if I'm "over-importing" the store, causing some inefficient code. Either way I thought I'd let you know that I found this comment you made helpful:
|
@mweststrate I too would love to see some guidelines/best practices/examples around how best to import/inject stores in to components similar to @Kamaraju333 and @teesloane. I think mobx is awesome from what I've seen so far but all examples seem to focus on small applications with a few stores at most. I have a large application with dozens of stores and views and am finding it hard to wrap my head around how to use mobx in almost a 1 to 1 relationship between views and stores. |
I found this persons write up useful for people who are using React-Router with Mobx. http://frontendinsights.com/connect-mobx-react-router/ I'm wondering if anyone can weigh in on using the Provider to pass the stores down to components like this? Is there any good reason not to? It seems like it simply takes advantage of Router being the main container component for the app. |
I have seen a few references to accessing stores via context using |
What's the consensus on accessing the store from inside the component? Do you access it directly using import or pass as props?
Importing and accessing directly is very convenient, but how do you test it?
I started a new project a few weeks ago using Redux, and have migrated to using MobX completely. I pass store as props for easier testing. I use a decorator to pass the store:
My store looks like this:
I have
injectStore()
stored somewhere so I just import it when I need to use the store. Do you think this is viable? Will there be implications of passing a big fat store? My application seems working fine with it, but I'm still on the early stage of development.I like the idea of importing the store directly, it just feels normal and straightforward. I'm just not sure how to test it and if its considered an anti-pattern.
The text was updated successfully, but these errors were encountered: