我最近开始使用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;
答案 0 :(得分:0)
您过早取消引用值。
基本上,您创建了一些指向可观察对象的局部变量ingredients
,然后为该局部变量重新分配了另一个值。但是这个局部变量是不可观察的,因此MobX保持不变。同时this.ingredients
是可观察的属性,MobX跟踪访问并对其进行更改。