Javascript Mobx-改变反应内部的可观测阵列

Javascript Mobx-改变反应内部的可观测阵列,javascript,state,mobx,mobx-react,Javascript,State,Mobx,Mobx React,我最近开始使用MobX,我遇到了反应的概念。我把反应理解为产生副作用的功能。副作用是什么取决于我。我使用反应来更新我的MobX状态。如果你检查我下面的代码,我有一个项目(成分)状态。我想做的是从我的本地存储(functiongetcomponents)加载配料,并在我的React中显示它们。到现在为止,一直都还不错。然后,每当我更新成分时(更改名称、价格、重量-可通过表单编辑),我都希望将此更改存储在本地存储中(函数putComponent),然后相应地更新我的@可观察成分)(所以后来,当我去掉

我最近开始使用MobX,我遇到了
反应
的概念。我把反应理解为产生副作用的功能。副作用是什么取决于我。我使用反应来更新我的MobX状态。如果你检查我下面的代码,我有一个项目(成分)状态。我想做的是从我的本地存储(function
getcomponents
)加载配料,并在我的React中显示它们。到现在为止,一直都还不错。然后,每当我更新成分时(更改名称、价格、重量-可通过表单编辑),我都希望将此更改存储在本地存储中(函数
putComponent
),然后相应地更新我的
@可观察成分
)(所以后来,当我去掉
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
函数中,有一行被注释了。如果我取消注释这一行并注释上一行(
components=components.map(I=>I.id==component.id?component:I);
),脚本将起作用。我想,我可以通过重新分配新值来编辑可观察的变量。实际上,我已经在
getComponents
函数中这样做了,其中
getComponents
函数返回新数组。那么这里的诀窍是什么?为什么我会出现这个错误

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;

您过早地取消了对值的引用

基本上,您创建了一些局部变量
成分
,它指向可观察的对象,然后您用另一个值重新分配了这个局部变量。但是这个局部变量是不可观察的,所以对MobX没有任何更改。同时
这个。成分
是可观察的属性,MobX跟踪对它的访问和更改。


这里的更多信息:

我现在知道了什么。如果我不在
更新元素
函数中使用
{contracents}=this
并使用
this.contracents=this.contracents.map(…)
脚本按预期工作。