我应该如何使用 MobX 实现惰性行为?

How should I implement lazy behaviour with MobX?

以下代码旨在在添加新用户后立即打印用户的反向列表,但它不起作用。 auto运行 正在监听一个延迟计算的 var (_userArrayRev),但是如何启用该 var 的重新计算? auto运行 只执行一次,而我希望它是 运行 三次

而且,当 enforceactions (useStrict) 设置为 true 时,为什么 MobX 允许我在 AddUser() 中修改可观察的 userArray 变量?

import { useStrict, configure, autorun } from 'mobx';
import { observable, action, computed } from 'mobx';


configure({ enforceActions: true });


class Test {
    @observable _userArray = [];
    @observable _userArrayRev = undefined;
    userCount = 0;

    addUser() {
        console.log("Adduser");
        this._userArray.push('user' + this.userCount);
        this.invalidateCache();
    }

//  returns reversed array
    getUsersArrayRev() {
        if (this._userArrayRev == undefined) {
//          console.log("recalculating userArray");
            // TODO: should be reversed
            this._userArrayRev = this._userArray;
        }
        return this._userArrayRev;
    }

    invalidateCache() {
        this._usersArrayRev = undefined;
    }

}

var t = new Test();

autorun(function test () {
    console.log("users: ", t.getUsersArrayRev());
});
t.addUser();
t.addUser();

我建议您使用 computed 而不是 autoruncomputed 更适合基于 observable 对象创建只读惰性变量的情况。

注意:我使用slice()到return一个普通数组。 Observable 数组是一个对象而不是数组,请注意这一点。

import React from 'react';
import { render } from 'react-dom';
import { observer } from 'mobx-react';
import { observable, action, computed } from 'mobx';

class Test {
  @observable _userArray = [];

  @computed get userCount() {
    return this._userArray.length;
  }

  @computed get usersArrayRev() {
    return this._userArray.slice().reverse();
  }

  @action
  addUser() {
    console.log("Adduser");
    const id = this.userCount + 1;
    this._userArray.push(`user${id}`);
    console.log("Reversed users: ", this.usersArrayRev);
  }
}

@observer
class App extends React.Component {
  t = new Test();

  render() {
    return (
      <div>
        {this.t.usersArrayRev.map(user => <div key={user}>{user}</div>)}
        <button onClick={() => { this.t.addUser(); }}>Add user</button>
      </div>
    );
  }
}

此处的代码演示: