I get the following error: Error: [mobx] Invariant failed: It is not allowed to change the state when a computed value is being evaluated.
I am new to MobX, so there is some trial an error here. I think I am using @computed and autorun() incorrectly. I have a case with three classes and I will try to illustrate it.
class A {
@observable r = [];
constructor( dao ) {
this._dao = dao;
autorun( () => this.findSomething() );
}
findSomething() {
...
// this line causes the error. With or without then(...) does not matter.
// commenting the line out removes error and renders properly
this._dao.findSomething.then(...)
}
}
class Dao {
constructor( db ) {
this._db = db;
}
// returns promise
@computed get findSomething() {
return this._db.somecollection.find(...).then(...)
}
}
class B {
@observerble data = [];
constructor() {
autorun( () => this.loadData() );
}
// but this function throws the above invariant error
loadData() {
db.findData().then(...)
}
}
The classes A and B are used by two different React components and are renderd together. The goal is to have Dao use B.data, load reactively data from a local db, until A.r is changed and triggers a re-render.
What should be handled with autorun() and setting an @observable and what should be @computed?
Thanks
That error means you changing observable state inside @computed getter. You must have removed it from your code snippet, but I suspect there is something like (assuming, that _db.somecollection.find() works synchronously):
@computed get findSomething() {
return this._db.somecollection.find(...).then(something => { this.r = something; return something; })
}
Just use autorun for side effects and observable state modifications
And assuming that your .then() is not like Pomise.then(), otherwise @computed get returning promise doesn't makes sense to me
That error means you changing observable state inside @computed getter.
Thanks, that clarifies it. I wanted the Dao to be reactive, but I changed it. I use autorun() in A to call the promise returning Dao.findSomething().
Most helpful comment
That error means you changing observable state inside
@computedgetter. You must have removed it from your code snippet, but I suspect there is something like (assuming, that_db.somecollection.find()works synchronously):Just use
autorunfor side effects and observable state modifications