【问题标题】:React state updating without reason无故响应状态更新
【发布时间】:2019-01-07 00:55:06
【问题描述】:

我的问题很容易理解。

我所在的州有一个用户列表。由数据库调用填充。 当单击用户列表中的元素时,我还填充了一个 selecteduser。

当单击用户列表中的此元素时,将打开一个模式,其中输入的默认值由 selecteduser 填充。

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

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

除了来自数据库的数据调用之外,这个用户列表在代码中没有任何 setState。

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

然后调用userlist存储数据。

 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),我可以看到用户列表也更新了。

我想清楚,但我希望它不会太长。

提前致谢:)

【问题讨论】:

    标签: javascript reactjs state


    【解决方案1】:

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

    {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}
        />
      );
    })}
    

    【讨论】:

      猜你喜欢
      • 2021-03-21
      • 1970-01-01
      • 2021-06-02
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多