如何更新 Mobx 可观察数组中的对象
How to update object in Mobx observable array
Codesandbox问题:
https://codesandbox.io/s/serverless-thunder-6gj04?file=/src/store.js
我有以下商店:
class PersonStore {
persons = [];
constructor() {
makeAutoObservable(this, {}, { autoBind: true });
}
*fetchPersons() {
const response = yield fetch(
"https://random-data-api.com/api/users/random_user?size=5"
);
this.persons = yield response.json();
}
}
export default new PersonStore();
现在,我想更新人员列表中的人员。
当我像这样更新数组内项目的单个字段时,它按预期工作并且 UI 更新:
update(id) {
let updated = this.persons.find((p) => p.id === id);
// This works...
updated.first_name = "FOO";
}
但是,将来我想将更复杂的更新数据传递到此函数中。所以我的想法是基本上用列表中的更新值分配一个全新的对象。
不幸的是,这并没有像我预期的那样工作:
update(id) {
let updated = this.persons.find((p) => p.id === id);
// This does not work...
const dummy_person = { first_name: 'foo', last_name: 'bar', id: 99 }
updated = dummy_person
}
我的第一个猜测是这不起作用,因为数组中的对象不是“普通对象”而是可观察对象。所以我为这些人创建了一个模型:
class Person {
id = null;
first_name = "";
last_name = "";
constructor() {
makeAutoObservable(this);
this.first_name = "FOO";
this.last_name = "BAR";
}
}
...但这仍然不起作用...
update(id) {
let updated = this.persons.find((p) => p.id === id);
// This does not work...
const dummy_person = new Person()
updated = person
}
如何用包含更新数据的对象“替换”数组中的对象?
正如@Tholle 在评论中所说,您只是在更新局部变量,而不是实际对象。
简单来说,这就是您的 update
函数中发生的事情:
let updated = this.persons.find((p) => p.id === id);
- 您创建局部变量 updated
并为其分配一些对象(人)
const dummy_person = { first_name: 'foo', last_name: 'bar', id: 99 }
- 您创建虚拟对象并将其分配给本地 dummy_person
常量
updated = dummy_person
- 此处您将 dummy_person
值分配给 updated
变量。基本上你只重新分配 updated
变量的值,你不是在改变人对象,而只是改变到什么值 updated
变量点。
有时人们用盒子来解释它,比如想象 updated
是一个盒子,一开始你把 person
放在里面,然后你改变主意把 dummy_person
放在里面,但实际 person
没有改变。
那你能做什么?
正如@Tholle 所说,您可以使用splice
来更改persons
数组,它基本上会丢弃旧的人并插入新的人。
或者如果你真的想更新老人,你可以使用 Object.assign(updated, dummy_person)
或者你可以使用map
(尽管它会重新分配整个数组,有时可能是不必要的):
update(id) {
const dummy_person = { first_name: 'foo', last_name: 'bar', id: 99 };
this.persons = this.persons.map(person => person.id === id ? dummy_person : person);
}
你能做的很多,取决于你做什么。最主要的是了解反应性是如何工作的!
文档中有关此主题的更多信息:https://mobx.js.org/understanding-reactivity.html
Codesandbox问题: https://codesandbox.io/s/serverless-thunder-6gj04?file=/src/store.js
我有以下商店:
class PersonStore {
persons = [];
constructor() {
makeAutoObservable(this, {}, { autoBind: true });
}
*fetchPersons() {
const response = yield fetch(
"https://random-data-api.com/api/users/random_user?size=5"
);
this.persons = yield response.json();
}
}
export default new PersonStore();
现在,我想更新人员列表中的人员。
当我像这样更新数组内项目的单个字段时,它按预期工作并且 UI 更新:
update(id) {
let updated = this.persons.find((p) => p.id === id);
// This works...
updated.first_name = "FOO";
}
但是,将来我想将更复杂的更新数据传递到此函数中。所以我的想法是基本上用列表中的更新值分配一个全新的对象。
不幸的是,这并没有像我预期的那样工作:
update(id) {
let updated = this.persons.find((p) => p.id === id);
// This does not work...
const dummy_person = { first_name: 'foo', last_name: 'bar', id: 99 }
updated = dummy_person
}
我的第一个猜测是这不起作用,因为数组中的对象不是“普通对象”而是可观察对象。所以我为这些人创建了一个模型:
class Person {
id = null;
first_name = "";
last_name = "";
constructor() {
makeAutoObservable(this);
this.first_name = "FOO";
this.last_name = "BAR";
}
}
...但这仍然不起作用...
update(id) {
let updated = this.persons.find((p) => p.id === id);
// This does not work...
const dummy_person = new Person()
updated = person
}
如何用包含更新数据的对象“替换”数组中的对象?
正如@Tholle 在评论中所说,您只是在更新局部变量,而不是实际对象。
简单来说,这就是您的 update
函数中发生的事情:
let updated = this.persons.find((p) => p.id === id);
- 您创建局部变量updated
并为其分配一些对象(人)const dummy_person = { first_name: 'foo', last_name: 'bar', id: 99 }
- 您创建虚拟对象并将其分配给本地dummy_person
常量updated = dummy_person
- 此处您将 dummy_person
值分配给updated
变量。基本上你只重新分配updated
变量的值,你不是在改变人对象,而只是改变到什么值updated
变量点。
有时人们用盒子来解释它,比如想象 updated
是一个盒子,一开始你把 person
放在里面,然后你改变主意把 dummy_person
放在里面,但实际 person
没有改变。
那你能做什么?
正如@Tholle 所说,您可以使用splice
来更改persons
数组,它基本上会丢弃旧的人并插入新的人。
或者如果你真的想更新老人,你可以使用 Object.assign(updated, dummy_person)
或者你可以使用map
(尽管它会重新分配整个数组,有时可能是不必要的):
update(id) {
const dummy_person = { first_name: 'foo', last_name: 'bar', id: 99 };
this.persons = this.persons.map(person => person.id === id ? dummy_person : person);
}
你能做的很多,取决于你做什么。最主要的是了解反应性是如何工作的!
文档中有关此主题的更多信息:https://mobx.js.org/understanding-reactivity.html