为什么当我将 @action 装饰器添加到反应事件处理函数时组件没有重新渲染
Why does the component is not re-rendering when i add @action decorator to an react event handler function
问题:
当我将 @action 装饰器添加到 class 成员 fn 时,下面的反应组件不会重新呈现。
import { observable, action } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
import { render } from "react-dom";
@observer
class PriceCounter extends React.Component {
@observable price = 0;
@action
setPrice = () => {
this.price = this.price + 1;
};
@action
currentPrice = () => {
return this.price;
}
render() {
return (
<div>
<span className="text-3xl">Total: {this.currentPrice()}</span>
<button onClick={this.setPrice}>Change details</button>
</div>
);
}
}
render(<PriceCounter />, document.getElementById("root"));
- 当从 currentPrice fn 中删除 @action 时,PriceCounter 组件会按预期重新呈现。
Why? Explanation needed.
要么你可以使用this.price来显示价格的更新值。或者你可以使用计算装饰器来做到这一点。
@observer
class PriceCounter extends React.Component {
@observable price = 0;
@action
setPrice = () => {
this.price = this.price + 1;
};
@computed
get currentPrice() {
return this.price;
}
render() {
return (
<div>
<span className="text-3xl">Total: {this.currentPrice}</span>
<button onClick={this.setPrice}>Change details</button>
</div>
);
}
}
或
@observer
class PriceCounter extends React.Component {
@observable price = 0;
@action
setPrice = () => {
this.price = this.price + 1;
};
@action
currentPrice = () => {
return this.price;
};
render() {
return (
<div>
<span className="text-3xl">Total: {this.price}</span>
<button onClick={this.setPrice}>Change details</button>
</div>
);
}
}
这是错误的操作用法。
@action
预计将围绕一个可观察量发生变化的函数进行包装。在这里,您没有更改 currentPrice
函数中的任何可观察值。
因为 render 是 mobx-react 中的一个跟踪函数,如果你没有用 action 包装 currentPrice
函数 & 如果你调用 this.currentPrice()
mobx 跟踪那个函数中使用的可观察对象。
如果您正在使用带有动作的跟踪函数包装函数,mobx 不知道您是打算跟踪可观察对象还是想 运行 在函数执行后跟踪函数。
动作应该只并且总是用于修改状态的函数。看看When to use actions
在您提到的示例中,currentPrice
方法未修改状态。所以你不需要为此使用动作装饰器。
问题:
当我将 @action 装饰器添加到 class 成员 fn 时,下面的反应组件不会重新呈现。
import { observable, action } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
import { render } from "react-dom";
@observer
class PriceCounter extends React.Component {
@observable price = 0;
@action
setPrice = () => {
this.price = this.price + 1;
};
@action
currentPrice = () => {
return this.price;
}
render() {
return (
<div>
<span className="text-3xl">Total: {this.currentPrice()}</span>
<button onClick={this.setPrice}>Change details</button>
</div>
);
}
}
render(<PriceCounter />, document.getElementById("root"));
- 当从 currentPrice fn 中删除 @action 时,PriceCounter 组件会按预期重新呈现。
Why? Explanation needed.
要么你可以使用this.price来显示价格的更新值。或者你可以使用计算装饰器来做到这一点。
@observer
class PriceCounter extends React.Component {
@observable price = 0;
@action
setPrice = () => {
this.price = this.price + 1;
};
@computed
get currentPrice() {
return this.price;
}
render() {
return (
<div>
<span className="text-3xl">Total: {this.currentPrice}</span>
<button onClick={this.setPrice}>Change details</button>
</div>
);
}
}
或
@observer
class PriceCounter extends React.Component {
@observable price = 0;
@action
setPrice = () => {
this.price = this.price + 1;
};
@action
currentPrice = () => {
return this.price;
};
render() {
return (
<div>
<span className="text-3xl">Total: {this.price}</span>
<button onClick={this.setPrice}>Change details</button>
</div>
);
}
}
这是错误的操作用法。
@action
预计将围绕一个可观察量发生变化的函数进行包装。在这里,您没有更改 currentPrice
函数中的任何可观察值。
因为 render 是 mobx-react 中的一个跟踪函数,如果你没有用 action 包装 currentPrice
函数 & 如果你调用 this.currentPrice()
mobx 跟踪那个函数中使用的可观察对象。
如果您正在使用带有动作的跟踪函数包装函数,mobx 不知道您是打算跟踪可观察对象还是想 运行 在函数执行后跟踪函数。
动作应该只并且总是用于修改状态的函数。看看When to use actions
在您提到的示例中,currentPrice
方法未修改状态。所以你不需要为此使用动作装饰器。