Mobx-在反应内部更改可观察的数组

时间:2020-03-05 12:19:19

标签: javascript state mobx mobx-react

我最近开始使用MobX,并且遇到了reaction概念。我将reactions理解为具有副作用的函数。副作用是我自己决定的。我使用反应来更新MobX状态。如果您在下面查看我的代码,则说明项目(成分)的状态。我要做的是从localStorage(功能getIngredients)中加载成分并将其显示在我的React中。到现在为止还挺好。然后,每当我更新成分(更改名称,价格,重量-可以通过表格对其进行编辑)时,我都希望将此更改存储在localStorage中(函数putIngredient),然后相应地更新我的@observable ingredients(因此稍后,当我摆脱localStorage并将其替换为数据库时,我会跟踪MobX中的更改)。我以为使用MobX reaction是一个很好的主意,但是当我尝试运行updateIngredients函数时,出现了以下错误:

Encountered an uncaught exception that was thrown by a reaction or observer component, in: 'Reaction[Reaction@1]' Error: "ingredients" is read-only

您可以看到,在updateIngredients函数内部,有一行注释。如果我取消注释此行并注释上一行(ingredients = ingredients.map(i => i.id === ingredient.id ? ingredient : i);),脚本将起作用。我以为,只要将新值重新分配即可编辑observable变量。实际上,我已经在getIngredients函数中做到了这一点,其中getIngredients函数返回了新数组。那么,这里的窍门是什么?为什么我会收到此错误?

import { observable, action, reaction } from 'mobx';

import { getIngredients, putIngredient } from './localStorage';

class Ingredients {
  @observable ingredients = [];
  @observable updatedIngredient = null;

  @action.bound getIngredients(opts = {}) {
    this.ingredients = getIngredients({ ...opts });
  }

  @action.bound async putIngredient(ingredient) {
    putIngredient(ingredient);
    this.updatedIngredient = ingredient;
  }

  @action.bound updateIngredients(ingredient) {
    const { ingredients } = this;
    ingredients = ingredients.map(i => i.id === ingredient.id ? ingredient : i);
    // ingredients.replace(ingredients.map(i => i.id === ingredient.id ? ingredient : i));
  }
}

const IngredientsStore = new Ingredients();

reaction(
  () => IngredientsStore.updatedIngredient,
  (updatedIngredient) => {
    if (updatedIngredient) {
      IngredientsStore.updateIngredients(updatedIngredient);
    }
  }
)

export default IngredientsStore;

1 个答案:

答案 0 :(得分:0)

您过早取消引用值。

基本上,您创建了一些指向可观察对象的局部变量ingredients,然后为该局部变量重新分配了另一个值。但是这个局部变量是不可观察的,因此MobX保持不变。同时this.ingredients是可观察的属性,MobX跟踪访问并对其进行更改。

此处有更多信息:https://mobx.js.org/best/react.html