Javascript 如何在Mobx可观测数组中更新对象

Javascript 如何在Mobx可观测数组中更新对象,javascript,reactjs,mobx,mobx-react,Javascript,Reactjs,Mobx,Mobx React,解决问题的代码沙盒: 我有以下商店: class个人商店{ 人员=[]; 构造函数(){ makeAutoObservable(this,{},{autoBind:true}); } *个人({ const response=yield fetch( "https://random-data-api.com/api/users/random_user?size=5" ); this.persons=yield response.json(); } } 导出默认的新PersonStore();

解决问题的代码沙盒:

我有以下商店:

class个人商店{
人员=[];
构造函数(){
makeAutoObservable(this,{},{autoBind:true});
}
*个人({
const response=yield fetch(
"https://random-data-api.com/api/users/random_user?size=5"
);
this.persons=yield response.json();
}
}
导出默认的新PersonStore();
现在,我想更新人员列表中的人员

当我像这样更新数组中项目的单个字段时,它会按预期工作,并且UI会更新:

更新(id){
让updated=this.persons.find((p)=>p.id==id);
//这很有效。。。
已更新。first_name=“FOO”;
}
但是,将来我希望将更复杂、更新的数据传递到此函数中。所以我的想法是基本上分配一个全新的对象,并在列表中更新值

不幸的是,这并不像我预期的那样有效:

更新(id){
让updated=this.persons.find((p)=>p.id==id);
//这不管用。。。
const dummy_person={first_name:'foo',last_name:'bar',id:99}
更新=虚拟人
}
我的第一个猜测是,这不起作用,因为数组中的对象不是“普通对象”,而是可观察对象。因此,我为这些人创建了一个模型:

班级人员{
id=null;
名字=”;
姓氏=”;
构造函数(){
使自动可观察(此);
此文件名为:this.first_name=“FOO”;
this.last_name=“BAR”;
}
}
…但这仍然不起作用

更新(id){
让updated=this.persons.find((p)=>p.id==id);
//这不管用。。。
const dummy_person=新人员()
更新=人
}

如何用包含更新数据的对象“替换”数组中的对象?

正如@Tholle在评论中所说,您只更新局部变量,而不是实际对象

简单地说,这就是
update
函数中发生的情况:

  • let updated=this.persons.find((p)=>p.id==id)-创建局部变量
    更新后的
    ,并为其分配一些对象(人员)

  • const dummy\u person={first\u name:'foo',last\u name:'bar',id:99}
    -创建虚拟对象并将其分配给本地
    dummy\u person
    常量

  • updated=dummy\u person
    -这里您将
    dummy\u person
    值分配给
    updated
    变量。基本上,您只需重新分配
    updated
    变量的值,而不是更改person对象,而是只更改为
    updated
    变量点的值

  • 有时人们用方框来解释它,比如想象一下,
    更新后的
    是一个方框,起初你把
    放在里面,然后改变主意,把
    虚拟人
    放在里面,但实际的
    没有改变

    那你能做什么呢

    正如@Tholle所说,您可以使用
    splice
    来更改
    persons
    数组,它基本上会丢弃旧的persons并插入新的persons

    或者,如果您真的想更新老人,您可以使用
    Object.assign(更新后的虚拟人)

    或者您可以使用
    map
    (虽然它会重新分配整个数组,但有时可能不需要):

    你能做的事情很多,取决于你做了什么。最重要的是了解反应性是如何工作的


    有关此主题的更多信息,请参阅文档:

    当您编写
    updated=dummy\u person
    时,您仅使用新值更新
    updated
    引用。MobX在该阶段没有参与。您可以尝试这样做:
    让updatedIndex=this.persons.findIndex((p)=>p.id==id);此.persons.splice(更新的索引,1,虚拟人)更新的。first_name=“FOO”
    那么,当它应该是一个局部变量时,它还能工作?!因为使用第一种方法,您实际上是在访问(“点入”)person对象属性。基本上,你说的是“更改
    更新的
    盒子的名字”
    
      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);
      }