Согласно официальной документации 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 регистрируется дважды?