setState不更新对象数组的值

时间:2017-09-26 08:52:15

标签: reactjs

我正在尝试使用以下函数更新users组件内的Users对象数组:

  updateUser = (index, user) => {
    let temp = this.state.users;
    temp[index] = user;
    this.setState({users: temp});
    console.log(this.state.users);
    console.log(temp);
  }        

这样做会给我以下警告:

  

proxyConsole.js:56警告:setState(...):只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState()。这是一个无操作。请检查Users组件的代码。

日志输出如下:
enter image description here

请注意:

  • 从另一个组件调用此函数以从用户数组更新单个用户。但值不是持久。只要我用另一个/新值调用此函数,旧的更新就不会保留。
  • 我的目标是在修改数组后立即重新渲染所有组件 Edit1:我有四个组成部分: IE浏览器。 Users组件正在调用List,正在调用User,并且正在调用UserDetail

Users组件:

import React, { Component } from 'react';
import List from './list';
import '../App.css';

class Users extends Component {
  constructor(){
    super();
    this.state = {
      users:[
        {firstName: "John", lastName: "Doe", email: "John@mail.com", company: "Monsters Inc."},
        {firstName: "Tom", lastName: "Riddle", email: "Tom@mail.com", company: "Slytherin Inc."},
        {firstName: "Harry", lastName: "Potter", email: "Harry@mail.com", company: "Gryffindor Inc."}
      ],
      adding: false
    }
  }

  updateUser = (index, user) => {
    let temp = this.state.users;
    temp[index] = user;
    this.setState({users: temp});
    console.log(this.state.users);
    console.log(temp);
  }

  render() {
    return (
        <div>
          <button onClick={this.addingMode}>ADD</button>
          <List data={this.state.users} remover={this.remover} updateUser={this.updateUser}/>
        </div>
      );
    }
}

export default Users;

List组件:

class List extends Component {
  render() {
    return (
      <div style={{textAlign:"Left"}}>
        {this.props.data.map((profile, i) =>
          <User key={i} id={i} data={profile} remover={this.props.remover} updateUser={this.props.updateUser}/>
        )}
      </div>
    );
  }
}

User组件:

import React, { Component } from 'react';
import '../App.css';
import UserDetails from './userDetails';
import {withRouter} from 'react-router';

class User extends Component {
  constructor(props){
    super(props);
    this.state = {
      editing: false,
      text: ""
    };
  };

  showUserDetails = () => {
    this.props.history.push({
      pathname: '/details',
      state: { data: this.props.data, id: this.props.id },
      updateUser: this.props.updateUser
    });
  };

  render() {
    return(
    <div>
      <h4>{this.props.data.firstName}</h4>
      <button onClick={this.showUserDetails}>View</button>
      <button>Remove</button>
    </div>
    );
  }
}

export default withRouter(User);          

UserDetails组件:

import React, { Component } from 'react';
import '../App.css';
import User from './user';

class UserDetails extends Component {
  constructor(props){
    super(props);
    this.state = {
      isEditModeEnabled: false,
      firstName: this.props.location.state.data.firstName,
      lastName: this.props.location.state.data.lastName,
      email: this.props.location.state.data.email,
      company: this.props.location.state.data.company
    };
  }

  editButton = () => {
    this.setState({isEditModeEnabled: true});
  }

  updateButton = () => {
    this.setState({isEditModeEnabled: false});
    //console.log(this.props.location);
    this.props.location.updateUser(
      this.props.location.state.id,
      { "firstName": this.state.firstName,
        "lastName": this.state.lastName,
        "email": this.state.email,
        "company": this.state.company
      }
    );
  }

  editing = (event) => {
    if (event.target.name === "firstName") {
      this.setState({firstName: event.target.value});
    } else if (event.target.name === "lastName") {
      this.setState({lastName: event.target.value});
    } else if (event.target.name === "email") {
      this.setState({email: event.target.value});
    } else {
      this.setState({company: event.target.value});
    }
  }

  render() {
    if (this.state.isEditModeEnabled) {
      return (
        <div>
          <b>First Name: </b><textarea defaultValue={this.state.firstName} onChange={this.editing} name="firstName"></textarea><br/>
          <b>Last Name: </b><textarea defaultValue={this.state.lastName} onChange={this.editing} name="lastName"></textarea><br/>
          <b>Email: </b><textarea defaultValue={this.state.email} onChange={this.editing} name="email"></textarea><br/>
          <b>Company: </b><textarea defaultValue={this.state.company} onChange={this.editing} name="company"></textarea><br/>
          <button onClick={this.updateButton}>Update</button>
        </div>
      );
    } else {
      return (
        <div>
          <b>First Name: </b>{this.props.location.state.data.firstName}<br/>
          <b>Last Name: </b>{this.props.location.state.data.lastName}<br/>
          <b>Email: </b>{this.props.location.state.data.email}<br/>
          <b>Company: </b>{this.props.location.state.data.company}<br/>
          <button onClick={this.editButton}>Edit</button>
        </div>
      );
    }
  }
}

export default UserDetails;

1 个答案:

答案 0 :(得分:-1)

可能是因为setState是异步的。这意味着console.log()之后的setState会向您提供虚假信息。使用callback setState功能确定state更改:

this.setState({users: temp}, () => console.log(this.state.users));

您应该分享更多的组件,以确定您面临的真正问题。很难说出你真正要做的是什么,因为你共享的代码片段指向异步问题,而你的描述和警告指向另一个。