diff --git a/src/core/derivation.ts b/src/core/derivation.ts index 203b65425..7599b8ccc 100644 --- a/src/core/derivation.ts +++ b/src/core/derivation.ts @@ -135,8 +135,17 @@ export function isComputingDerivation() { } export function checkIfStateModificationsAreAllowed(atom: IAtom) { + const hasObservers = atom.observers.size > 0 + // Should never be possible to change an observed observable from inside computed, see #798 + if (globalState.computationDepth > 0 && hasObservers) + fail( + process.env.NODE_ENV !== "production" && + `Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ${ + atom.name + }` + ) // Should not be possible to change observed state outside strict mode, except during initialization, see #563 - if (!globalState.allowStateChanges && (atom.observers.size > 0 || globalState.enforceActions === "strict")) + if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "strict")) fail( process.env.NODE_ENV !== "production" && (globalState.enforceActions diff --git a/test/base/action.js b/test/base/action.js index b8db892ec..0e96f07a5 100644 --- a/test/base/action.js +++ b/test/base/action.js @@ -202,30 +202,6 @@ test("should be possible to change observed state in an action called from compu d() }) -test("should be possible to change observed state in an action called from computed if run inside _allowStateChangesInsideComputed - 2", () => { - const a = mobx.observable.box(2) - const d = mobx.autorun(() => { - a.get() - }) - - const testAction = mobx.action(() => { - a.set(3) - }) - - const c = mobx.computed(() => { - mobx._allowStateChanges(true, () => { - testAction() - }) - return a.get() - }) - - c.get() - - mobx._resetGlobalState() - d() -}) - - test("should not be possible to change observed state in an action called from computed", () => { var a = mobx.observable.box(2) var d = mobx.autorun(() => {