-
-
Notifications
You must be signed in to change notification settings - Fork 349
inject with custom mapper function is not reactive #302
Comments
The problem is that inject(({ store }) => ({
list: store.state.list.slice() // or toJS(store.state.list),
addItem: store.addItem,
})) This would work as well, but it's a bit "artificial/hacky" solution: inject(({ store }) => ({
listLength: store.state.list.length, // now we have subscribed for a change of the array itself
list: store.state.list,
addItem: store.addItem,
})) The difference between the |
Hello @urugator, thanks for the feedback. Indeed, converting the observableArray to a plain old javascript array would work. BTW I think that is the way 'mobdux' works. However, even if the inject function was not designed to be used way, I do think that providing a method in the public API that would inject + observe would be great. If I understand correctly, it is the reason why inject was made reactive to the mapper function in the first place, according to #111 and the SO post linked in the issue. I am thinking of a Redux-like connect function , as mobdux is doing, or as used in mobx-react tests themselves. What do you think ? |
Imho connect like approach goes against the MobX philosophy. If it's just about being lazy to write |
Thanks for you answer ! You're probably right. In the end, I guess it's about being lazy to write I'm a big fan of how Mobx automagically handles subscription for us. At the same time, most of the examples I found (and most of the components I wrote) use directly values from the store in the components. In our codebase, this results in parsing and formatting in render functions and our components tend to become less and less readable. IMHO it seems great in terms of separation of concerns to have a layer of abstraction so that we can better decouple the view and the stores. I guess there are (at least) two ways to implement a connect like functionality with mobx-react connect(({mainStore}) => ({
list: mainStore.state.list
}))({list}) => (
<ul>...</ul>
))
inject(({mainStore}) => ({
list: mainStore.state.list.peek() // or Mobx.toJS
}))({list}) => (
<ul>...</ul>
))
inject(({mainStore}) => ({
list: mainStore.state.list // Mobx ObservableArray
}))(observer({list}) => (
<ul>...</ul>
))) I can see how using the 1st approach would go against mobx's philosophy because we would be declaring the subscriptions manually. With the second approach, though, I think it's not about declaring subscriptions, but rather to abstract them for the view as readable variable with names that make sense. It seems to provides a very good solution to the challenge of separating the view and the data, while keeping the views reactive. Do you see disadvantages in using the 2d way, or should I expect to run into problems using this pattern ? P.S. I guess the @connect decorator would make sense too |
If you use it only as an adapter to bridge between store and component API, I wouldn't expect any problems. inject(store => {
name: computed(() => store.name) // store.name is string
})
// now you can still pass the "name" alone to descendants while keeping it observable So you can get rid of the direct dependency on store, but you won't get rid of the depedency on observables. Whether you need such abstraction is up to you.
Can you elaborate? Post an example perhaps? |
For clarity; it is not the code literally in the |
Closing as original question seems answered. |
I read about 'mobdux' and I wanted to give this pattern a try, using inject to decouple the store values and the component. Unfortunately in some cases, the view does not update with the store changes
Simple example :

When using inject with a custom function like so :
with list being a list of strings, the changes on
store.state.list
do not reflect on the view.In order to have the view react to the changes on the todo list, I have to use observer on top of inject :
I'm not sure what is the expected behaviour, but I think it is better if the view updates automatically with inject
For now I am using a custom function
connect
:so that we don't have to manually call observer each time.
I am guessing it might also be related to this comment on the 'mobdux' post that uses inject internally : https://medium.com/@vlopezsalvador.22/great-article-cameron-fletcher-could-you-give-me-a-hint-about-this-issue-i-am-having-6cdef64f5db8
Anyway, great work on Mobx ! Amazing DX 👍
The text was updated successfully, but these errors were encountered: