简体   繁体   中英

Why is mobx observable property of js class not tracked, but property of mobx observable object is?

I'm new to mobx and I wanted to do a quick test of Mobx to see how can I fit it to my project.

When I run this code

class Entity{
   @observable version = 1;
}

let testEntity = new Entity();

let disposer = autorun(() => console.log(`Entity version : ${testEntity.version}`));

testEntity.version = 2;
testEntity.version = 3;

disposer();

I expect to see this output

Entity version : 1
Entity version : 2
Entity version : 3

But, instead, I see only Entity version: 1

But if I use an observable plain object instead of class with observable properties, I get the desired output. Example:

let testEntity = observable({ version: 1 });

let disposer = autorun(() => console.log(`Entity version : ${testEntity.version}`));

testEntity.version = 2;
testEntity.version = 3;

disposer();
// this works and I see autorun firing three times instead of only the first.

So I thought I should make the class instance observable.

I used let testEntity = observable(new Entity()); but this threw an error about some .box function.

I tried again, this time with let testEntity =observable.box(new Entity()); and I had no errors.

But this time I got this result Entity version: undefined

What is going on here, and how can I achieve observable class instances?

Maybe I am following the wrong approach to my problem. I want to have my domain objects as class instances to add some business logic, and data manipulation inside them.

I have read the article about what mobx tracks and what it doesn't track, but it seems I still miss something.

I haven't used autorun a lot, but I think problem is that you're calling autorun outside of the class. Try moving that line of code to within your class:

class Entity{
   @observable version = 1;

   let disposer = autorun(() => console.log(`Entity version : ${version}`));
}

let testEntity = new Entity();



testEntity.version = 2;
testEntity.version = 3;

testEntity.disposer();

Thanks for the example, however, I tested your code and it works perfectly fine and we even don't need to save the return from autorun in the disposer.

Following is the test snippet, which works perfectly, ie it prints console 3 times, with updated values.

import { observable, autorun } from 'mobx';
class Entity {
  @observable version = 1;
}

let testEntity = new Entity();

autorun(() => console.log(`Entity version : ${testEntity.version}`));

testEntity.version = 2;
testEntity.version = 3;
// prints
Entity version : 1
Entity version : 2
Entity version : 3

----------------------------------------

/* Taking autorun inside class is fine either */
class Entity {
  @observable version = 1;
  disposer = autorun(() => console.log(`Entity version : ${this.version}`));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM