如何使简单的 mobx 反应在子组件中工作

How to make simple mobx reaction work in sub component

我错过了 mobx 观察和反应中的一些东西。 我准备了两个例子,一个可以,一个不行,我不明白为什么。

示例 1(不起作用):

@observer class Alert1 extends Component {
  constructor(props) {
    super(props);
    this.r2 = reaction(
      () => this.props.v1,
      v => console.log("Alert1 reaction trigger",v)
    );
  }
  render() {
    return null;
  }
}

@observer class Main extends Component {
  @observable v1 = false;
  render() {
    return (
      <div>
        <Alert1 v1={this.v1} />
        <button onClick={e=>this.v1=!this.v1}>Switch</button>
      </div>
    );
  }
}

在示例 1 中,我们只是在 props 中发送可观察变量并在 Alert1 组件中创建反应,但它不会触发。

示例 2(有效):

@observer class Alert2 extends Component {
  constructor(props) {
    super(props);
    this.r2 = reaction(
      () => this.props.someObj.v1,
      v => console.log("Alert2 reaction trigger",v)
    );
  }
  render() {
    return null;
  }
}

@observer class Main extends Component {
  constructor(props) {
    this.someObj = observable({v1:observable(false)});
  }
  render() {
    return (
      <div>
        <Alert2 someObj={this.someObj} />
        <button onClick={e=>this.someObj.v1=!this.someObj.v1}>Switch</button>
      </div>
    );
  }
}

这与示例 1 几乎相同,但我们将 v1 observable 包装到另一个 observable 中。 Alert2 反应有效。

同时,如果我们将反应从 Alert1 和 Alert2 组件移动到 Main 组件的构造函数,两个反应都会起作用。

这是包含两个组件的 jsfiddle 示例,https://jsfiddle.net/kasheftin/zex0qjvf/1/

请参阅 https://mobxjs.github.io/mobx/best/react.html,在您的第一个示例中,您没有传递一个可观察对象,而只是传递一个普通的布尔值(truefalse),因此没有用于反应的反应。在 javascript 中,所有 都是不可变的,因此根据定义,某些东西是可观察的。可以观察到的是 属性

在第二个示例中,您传递了一个具有可观察对象 属性 的对象,因此这是可以做出反应的对象。

请注意,创建一个 boxed 可观察对象也可以,因为它们可以作为第一批 class 公民传递。例如:v1 = observable(false)reaction(() => this.props.v1.get(), ...