我的问题很容易理解。

我的状态下有一个用户列表。由数据库调用填充。
当单击用户列表中的元素时,我也会填充一个selecteduser。

单击用户列表中的该元素时,将打开一个模态,其输入内容由selecteduser填充。

我将onChange函数分配给这些输入,然后将每个更改保存在selecteduser中。

但是问题是,每个更改也都保存在用户列表中,我真的不明白为什么。

该用户列表在代码中没有任何setState,除了数据库中的数据调用。

class Users extends Component {
 constructor(props) {
  super(props);
   this.state = {
    userlist: [],
    selecteduser: [],
    IsModalUserVisible: false
   };
 }


然后调用并将数据存储在用户列表中。

 componentWillMount() {
 db.collection("user")
 .get()
 .then(collection => {
   this.setState({
     userlist: collection.docs.map(doc => doc.data())
   });
 });
}


这是来自输入的onChange

handleChangeEmail(event) {
 event.preventDefault();
 const selectedUserUpdate = this.state.selecteduser;
 selectedUserUpdate.email = event.target.value;
 this.setState({
  selecteduser: selectedUserUpdate
 });
}


在这里,在userlist元素上调用onClick的函数。

UserSelected(user) {
 this.setState({
    selecteduser: user,
    IsModalUserVisible: true
  });
}


userlist.map显示用户列表。

{this.state.userlist.map(user => {
  return (
    <UserItem
      callback={() => this.UserSelected(user)}
      key={user.email}
      email={user.email}
    />
  );
})}


最后,用户管理模式是在单击用户列表元素时打开的。

<ManageUserItem
   isOpen={this.state.IsModalUserVisible}
   email={this.state.selecteduser.email}
   changeEmail={this.handleChangeEmail.bind(this)}
/>


因此,当我在输入中更改电子邮件时,我可以在后台看到列表也发生了变化。我在handleChangeEmail中使用console.log(this.state.userlist)进行了检查,可以看到用户列表也进行了更新。

我想清楚一点,但我希望不久就可以阅读。

提前致谢 :)

最佳答案

userlist: collection.docs.map(doc => doc.data())创建一个Javascript数组,该数组在每个索引处都包含一个内存引用点,该引用指向doc.data()返回的数据。初始化<UserItem>组件时,将在userlist状态Array中为该组件提供相同的内存引用。单击用户时,该相同的引用将通过callback属性方法UserSelected传递,并且在该方法中,会将相同的内存引用分配给状态变量selecteduser。稍后,当为该选定用户处理电子邮件更改时,方法handleChangeEmail将对存储在两个位置(userlist数组和selecteduser对象)中的内存引用进行操作。当您更新对象引用的属性时,引用对象的任何其他位置将显示这种变异,因为它们指向相同的基础数据。我建议对此代码进行的一个较小更改是在constructor方法中,将selecteduser初始化为对象({}),而不是数组([]),因为selecteduser最终还是被分配了一个对象,而不是数组。最后,如果您希望selecteduseruserlist数组中引用的对象引用不同,则可以根据阵列。像这样:

{this.state.userlist.map(user => {
   // this is one way to do it, you can find others elsewhere on SO for more complex cases.
   // Look into, Javascript as a pass by reference language versus pass by value languages
   // and their nuances.
   const newObject = JSON.parse(JSON.stringify(user))
   return (
    <UserItem
      callback={() => this.UserSelected(newObject)}
      key={newObject.email}
      email={newObject.email}
    />
  );
})}

10-04 16:13