javascript - 无故响应状态更新
问题描述
我的问题很容易理解。
我在我的州有一个用户列表。由数据库调用填充。当单击用户列表中的元素时,我还填充了一个 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
});
}
这里的函数在用户列表元素上调用了 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
状态数组中相同的内存引用。单击用户时,相同的引用将通过callback
prop 方法传递,UserSelected
并且在该方法中,相同的内存引用被分配给 state 变量selecteduser
。稍后,当为该选定用户处理电子邮件更改时,该方法handleChangeEmail
对存储在两个位置的内存引用进行操作,userlist
数组和selecteduser
目的。当您更新 Object 引用的属性时,引用 Object 的任何其他位置都将显示这种突变,因为它们指向相同的基础数据。我建议对此代码进行的一个小改动是在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}
/>
);
})}
推荐阅读
- qt - 是否可以在 Qml 中强制更新事件?如果是这样怎么办?
- python - 使用字典更改变量的参数
- r - 在 R (Zendesk API) 中使用来自 API 的 JSON 数据
- reactjs - 如何使用 AntD 管理表中的行数?
- c++ - 如何从 WM_INPUT 原始数据中获取触摸屏协调
- python - 声明在 llvmlite 中返回 void 的函数时出现 AssertionError
- c# - 使用 lambda 中的单个 orderId 按最新日期时间过滤对象列表
- php - 这在 PHP 中有效吗?
- wordpress - wp-admin 页面的“此页面不起作用”
- python - 对给定列表顺序Python的数据框进行排序