我的问题很容易理解。
我的状态下有一个用户列表。由数据库调用填充。 而且,当单击用户列表中的元素时,我也会填充一个selecteduser。
单击用户列表中的此元素时,将打开一个模态,其输入内容由selecteduser填充。
我为这些输入分配了onChange函数,然后每个更改都保存在选定的用户中。
但是问题是,每个更改也都保存在用户列表中,我真的不明白为什么。
此用户列表在代码中没有任何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
});
}
这里是在用户列表元素上调用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)进行了检查,可以看到用户列表也进行了更新。
我想清楚一点,但我希望不久就可以阅读。
预先感谢:)
答案 0 :(得分:1)
userlist: collection.docs.map(doc => doc.data())
创建一个Javascript数组,该Javascript数组在每个索引处都包含一个指向doc.data()
返回的数据的内存引用点。初始化<UserItem>
组件时,将在userlist
状态数组中为该组件提供相同的内存引用。单击用户时,该相同的引用将通过callback
prop方法UserSelected
传递,并且在该方法中,相同的内存引用被分配给状态变量selecteduser
。稍后,当为该选定用户处理电子邮件更改时,方法handleChangeEmail
对存储在两个位置(userlist
数组和selecteduser
对象)中的内存引用进行操作。当您更新对象引用的属性时,引用对象的任何其他位置将显示这种变异,因为它们指向相同的基础数据。我建议对此代码进行一个小的更改,方法是在constructor
方法中,将selecteduser
初始化为对象({})而不是数组([]),因为最终分配了selecteduser
无论如何都是对象,而不是数组。最后,如果您希望selecteduser
与userlist
数组中引用的对象引用不同,则可以从每个引用的对象创建一个新的对象(从而创建一个新的对象引用)在userlist
数组中。像这样:
{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}
/>
);
})}