Почему computed регистрируется два раза, а не один раз? - PullRequest
2 голосов
/ 09 мая 2020
  • Согласно официальной документации mobx, я понял, что когда мы оборачиваем обработчики событий реакции с помощью @action, мы должны видеть, что производные от mobx fns должны быть пакетными - вычисляемые fns, fns исполнителя реакции, автозапуск fns.

  • Если мы увидим это в качестве примера, это будет выглядеть следующим образом:

Случай 1: Когда обработчик события реакции заключен в действие

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

class Person {
  @observable firstName = "Ramu";
  @observable lastName = "Ratnam";
  @observable initial = "K";

  @computed get fullName() {
    console.log("Computed");
    return this.firstName + " " + this.lastName + " " + this.initial;
  }

  @action
  changeFirstNameAndLastName = () => {
    this.firstName = "Mark";
    this.lastName = "Wayne";
    this.initial = "J";
  };

}

const newPerson = new Person();

// Reaction: log the profile info whenever it changes

// Example React component that observes state
const ProfileView = observer(props => {
  console.log("render ProfileView");

  return (
    <div>
      <p>{props.person.fullName}</p>
      <button onClick={props.person.changeFirstNameAndLastName}>
        Change first name and last name
      </button>
    </div>
  );
});

render(<ProfileView person={newPerson} />, document.getElementById("root"));

  • Когда пользователь нажимает кнопку Change first name and last name, то из-за пакетной обработки вычислений функция рендеринга ProfileView должна запускаться один раз, что, как и ожидалось

  • Когда мы удаляем @action в обработчик changeFirstNameAndLastName, так как реакция может по-прежнему пакетировать обновления состояния, поэтому вычисленный fn должен запускаться один раз, а рендеринг fn должен вызываться один раз

Вместо этого вычисляемая fn регистрируется дважды .

  • Проверьте Case 2 фрагмент на то же самое.

Случай 2: Когда обработчик события реакции не заключен в действие

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

class Person {
  @observable firstName = "Ramu";
  @observable lastName = "Ratnam";
  @observable initial = "K";

  @computed get fullName() {
    console.log("Computed");
    return this.firstName + " " + this.lastName + " " + this.initial;
  }

  changeFirstNameAndLastName = () => {
    this.firstName = "Mark";
    this.lastName = "Wayne";
    this.initial = "J";
  };

}

const newPerson = new Person();

// Reaction: log the profile info whenever it changes

// Example React component that observes state
const ProfileView = observer(props => {
  console.log("render ProfileView");

  return (
    <div>
      <p>{props.person.fullName}</p>
      <button onClick={props.person.changeFirstNameAndLastName}>
        Change first name and last name
      </button>
    </div>
  );
});

render(<ProfileView person={newPerson} />, document.getElementById("root"));

Примечание:

Если реагировать пакетно, обновления состояния внутри changeFirstNameAndLastName, тогда вычисленный fn должен регистрироваться один раз.

Если response не выполняет пакетную обработку обновлений состояния внутри changeFirstNameAndLastName, то вычисленное fn должно регистрироваться трижды .

Почему вместо этого вычисляемая fn регистрируется дважды?

...