当我将@action装饰器添加到react事件处理函数时,为什么组件没有重新渲染

问题描述 投票:1回答:3

问题:

当我将@action装饰器添加到类成员fn时,下面的react组件不会重新呈现。

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"));

  • PriceCounter组件在从currentPrice fn中删除@action时按预期重新渲染。

为什么?需要说明。

javascript reactjs mobx mobx-react mobx-utils
3个回答
1
投票

动作应仅且始终应用于修改状态的函数。看看When to use actions

在您提到的示例中,currentPrice方法未修改状态。因此,您无需为此使用动作装饰器。


1
投票

您都可以使用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>
    );
  }
}

1
投票

这是错误的操作用法。

@action预计将包裹在其中可观察物发生变化的函数周围。在这里,您未更改currentPrice功能中的任何可观察对象。

由于渲染是mobx反应中的跟踪函数,如果您不包装带动作的currentPrice函数且调用了this.currentPrice() mobx会跟踪该函数中使用的可观察对象。

如果您要用动作包装在跟踪函数中使用的函数,mobx不会知道您打算跟踪可观察对象还是要在执行函数后运行跟踪函数。

© www.soinside.com 2019 - 2024. All rights reserved.