Replies: 3 comments
-
The idea of actions in general is not to push them as deep as possible into the store, but pull them up to the 'event handlers' of your app. If you make actions like So instead pull your actions as far outward as possible (they can still wrap only one synchronous execution stack), such as an event handler, or the end of your async process where you update the observables. So a better solution is: constructor() {
makeObservable(this, {
name: observable,
})
}
init = async () => {
const ret = await something.DownloadAndGetName()
runInAction(() => {
this.name = ret.name
// and probably more
})
} If that feels verbose, just extract the update part entirely, so that you get something like: constructor() {
makeObservable(this, {
name: observable,
processInitResults: action
})
}
init = async () => {
const ret = await something.DownloadAndGetName()
processInitResults(res)
}
processInitResults(res) {
this.name = ret.name
// and probably more
} The boilerplate free way is to use constructor() {
makeObservable(this, {
name: observable,
init: flow // flow!
})
}
*init() {
const ret = yield something.DownloadAndGetName()
this.name = ret.name // flow's continue after the `yield`
// and more
} The rule of thumb of actions is that they should scope events that happen in your system, not individual mutations. For further details see the docs, we tried to explain the differences elaborately: https://mobx.js.org/actions.html#asynchronous-actions |
Beta Was this translation helpful? Give feedback.
-
@mweststrate thanks for the insights. This makes sense for group action updates in a single tick. However, as my primary use is with React which comes with a "BatchedUpdater" -- is mobx using this already? and if so / if not, whats the consideration as it relates to grouping action updates in a render cycle? The reason I ask is, I prefer to reduce cognitive load on optimizations during programming, I just want to consider architecture/optimization during the build out of my tools/architecture, and then just use the tools knowing they will take care of me and consider edge optimizations, etc... such in this case, action feels like this to me in mobx, so if the react batched updater can do the grouping for me, then I'd take that trade-off of less explicit actions for less things to remember |
Beta Was this translation helpful? Give feedback.
-
There are 2 differences:
1. react batching only solves it for 'observer', but not for reactions in
general
2. react batching only works for events that are triggered by react (e.g.
onClick). It doesn't batch for all other events that cause either state
updates or rendering, like receiving a websocket message (they might change
that in a next version of React, but for now there is no batching for
non-react events)
…On Wed, Oct 7, 2020 at 2:07 PM Peter Kieltyka ***@***.***> wrote:
@mweststrate <https://github.com/mweststrate> thanks for the insights.
This makes sense for group action updates in a single tick. However, as my
primary use is with React which comes with a "BatchedUpdater" -- is mobx
using this already? and if so / if not, whats the consideration as it
relates to grouping action updates in a render cycle?
The reason I ask is, I prefer to reduce cognitive load on optimizations
during programming, I just want to consider architecture/optimization
during the build out of my tools/architecture, and then just use the tools
knowing they will take care of me and consider edge optimizations, etc...
such in this case, action feels like this to me in mobx, so if the react
batched updater can do the grouping for me, then I'd take that trade-off of
less explicit actions for less things to remember
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2489 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAN4NBFIYLD4Q6Q6RCBCH3TSJRRZBANCNFSM4SGP6PIQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Hi there, we've recently upgraded our project to mobx6 which has been very easy from v5. However, now that strict mode is enabled (which we prefer), we're receiving a lot of warnings related to changing an observable outside of an action. This sounds all good, and we're happy to add setter methods where an observable can be mutated. The challenge however becomes related to a long standing challenge with changing observables within an async function / action.
Im trying to figure out the best pattern for designing scaffolding around my observables so they can trigger actions, and also keep boilerplate down to a minimum, as well keeping the stores and their observables intuitive for consumption/usage by other developers.
Here are two approaches I've been thinking about, but please let me know if there is something even better / cleaner.
Approach 1:
Approach 2:
In my own reflections, Approach 1 seems fine, but it will be a lot of boilerplate to create getters/setters for each method, and perhaps needs
name: action
in themakeObservable
call?Approach 2 is better as its less code, but, it means we need to make a setter
setOBSERVABLENAME
action for each observable we want to mutate. The issue isthis.name = s
can still be mutated by a developer outside of the action and it can cause unnoticed problems, so I'd prefer to not have that setter available. However, It makes me wonder why this can't be automated in the es6 proxy or the existing setter method?Beta Was this translation helpful? Give feedback.
All reactions