MobX 6: Preventing Duplicate Writes on Retrying Async Actions with makeAutoObservable
0 reputation · 06 Jan 2020, 16:59 UTC
0 reputation · 06 Jan 2020, 16:59 UTC
When using MobX 6’s makeAutoObservable, async methods are automatically treated as actions. If a method that returns a promise is retried (e.g., after a network failure), the promise resolution can trigger a separate action that writes the same data again, leading to duplicated state updates.
The default behavior of makeAutoObservable is to wrap every function returning a promise as an async action. There is no built‑in flag to suppress duplicate writes on retry, and manual refactoring to action wrappers may break existing observable configurations.
There is no documented strategy for detecting and preventing duplicate writes when the same async action is invoked multiple times before the previous promise resolves.
action wrapping?makeAutoObservable be configured to treat repeated async calls as idempotent, or is a custom wrapper required?28775 reputation · 07 Jan 2020, 00:46 UTC
To prevent duplicate writes during retries in MobX 6 when using makeAutoObservable, you must ensure the async action is defined as a standard class method rather than an arrow function or a dynamically created function. MobX 6 automatically binds class methods; maintaining a stable function reference ensures that retries are treated as calls to the same action rather than the creation of new, distinct action contexts.
The most effective way to mitigate duplicate writes without manual action wrapping is to track the pending state of the promise. Since makeAutoObservable cannot make an action inherently idempotent, you must implement a guard clause using an observable property.
isFetching) to track the lifecycle of the request.makeAutoObservable handles the binding correctly.class DataStore {
data = null;
isFetching = false;
constructor() {
makeAutoObservable(this);
}
async fetchData() {
if (this.isFetching) return; // Guard against duplicate concurrent writes
this.isFetching = true;
try {
const result = await api.getData();
this.data = result;
} finally {
this.isFetching = false;
}
}
}
Duplicate writes often occur when async logic is wrapped in a new function reference during a retry loop. In MobX 6, if a method is defined as an arrow function class field, it is not bound by makeAutoObservable in the same way a prototype method is. If your retry logic involves re-creating the function or passing an anonymous wrapper, MobX may trigger separate reactions for each instance.
By using a standard class method and a state-based guard, you ensure that only one logical flow can modify the observable state at a time, regardless of how many times the retry mechanism attempts to invoke the method.
try block from executing more than once until the first promise resolves.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.