ReactJS:对象在setState中更新,但未反映在UI中

问题描述 投票:0回答:5

我是ReactJS的新手。当我单击按钮时,呼叫将从createTablesam.js转到index.js以更新对象。对象在setState中成功更新,但在UI中未更新。如果再次单击该按钮,则对象正在更新,但UI未更新。

const PureComponent = React.PureComponent;

class Index extends PureComponent {
  constructor() {
    super();
    this.state = {
      userValues: [
        {
          name: "Mani",
          age: 23,
          skill: "Java"
        },
        {
          name: "Vel",
          age: 23,
          skill: "react"
        }
      ]
    };
    this.addRow = this.addRow.bind(this);
  }

  addRow() {
    let newdetails = {
      name: "ManiVEL",
      age: 25,
      skill: "REACT JS"
    };
    let userValues = this.state.userValues;
    userValues.push(newdetails);
    this.setState({
      userValues
    });
  }

  render() {
    return (
      <CreateTablesam
        addtable={this.addRow}
        tabelDeatils={this.state.userValues}
      ></CreateTablesam>
    );
  }
}

class CreateTablesam extends PureComponent {
  state = {
    tableCopy: this.props.tabelDeatils
  };

  render() {
    const createRow = this.state.tableCopy.map(per => (
      <tr key={per.name}>
        <td>{per.name}</td>
        <td>{per.age}</td>
        <td>{per.skill}</td>
      </tr>
    ));

    return (
      <div>
        <table>
          <thead>
            <tr>
              <td>Name</td>
              <td>Age</td>
              <td>skills</td>
            </tr>
          </thead>
          <tbody>{createRow}</tbody>
        </table>
        <button onClick={this.props.addtable}>CLICK</button>
      </div>
    );
  }
}

ReactDOM.render(<Index />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

我犯了什么错误?

reactjs setstate buttonclick
5个回答
1
投票

两个问题

  1. 不编辑现有数组,而是创建一个新数组。
  2. this.state = ...在每个组件实例中仅运行一次。并且由于您将tabelDeatils值存储在此处,因此永远不会更新。

更改如下

const PureComponent = React.PureComponent;

class Index extends PureComponent {
  constructor() {
    super();
    this.state = {
      userValues: [
        {
          name: "Mani",
          age: 23,
          skill: "Java"
        },
        {
          name: "Vel",
          age: 23,
          skill: "react"
        }
      ]
    };
    this.addRow = this.addRow.bind(this);
  }

  addRow() {
    let newdetails = {
      name: "ManiVEL",
      age: 25,
      skill: "REACT JS"
    };
    this.setState({
      userValues: [...this.state.userValues, newdetails]
    });
  }

  render() {
    return (
      <CreateTablesam
        addtable={this.addRow}
        tabelDeatils={this.state.userValues}
      ></CreateTablesam>
    );
  }
}

class CreateTablesam extends PureComponent {
  render() {
    const createRow = this.props.tabelDeatils.map(per => (
      <tr key={per.name}>
        <td>{per.name}</td>
        <td>{per.age}</td>
        <td>{per.skill}</td>
      </tr>
    ));

    return (
      <div>
        <table>
          <thead>
            <tr>
              <td>Name</td>
              <td>Age</td>
              <td>skills</td>
            </tr>
          </thead>
          <tbody>{createRow}</tbody>
        </table>
        <button onClick={this.props.addtable}>CLICK</button>
      </div>
    );
  }
}

ReactDOM.render(<Index />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

0
投票

您需要改进更新状态数组的方式。如评论部分所述,请阅读Correct modification of state arrays in ReactJS

您的情况是:this.setState({ userValues: [...this.state. userValues, newelement] })

一旦您具有上述要点,就需要改进密钥处理部分。请阅读:Understanding unique keys for array children in React.js

原因是表中的数据具有相同的键key={per.name}。由于您总是添加相同的记录,因此name属性将保持不变。因此,<tr key={per.name}>键将保持不变。尝试将不同的对象(至少具有不同的名称)添加到表中。


0
投票

React.PureComponent的shouldComponentUpdate()会跳过整个组件子树的道具更新。确保所有子组件也都是“纯”的。

这就是为什么您的道具不更新组件的原因。与React.Components一起尝试]


0
投票
class CreateTablesam extends PureComponent {
  render() {
    const createRow = this.props.tabelDeatils.map(per => (
      <tr key={per.name}>
        <td>{per.name}</td>
        <td>{per.age}</td>
        <td>{per.skill}</td>
      </tr>
    ));

    return (
      <div>
        <table>
          <thead>
            <tr>
              <td>Name</td>
              <td>Age</td>
              <td>skills</td>
            </tr>
          </thead>
          <tbody>{createRow}</tbody>
        </table>
        <button onClick={this.props.addtable}>CLICK</button>
      </div>
    );
   }
  }

0
投票

您正在直接更改addRow中的状态。复制userValues或使用setState的功能形式:

addRow() {
  let newdetails = {
    name: "ManiVEL",
    age: 25,
    skill: "REACT JS"
  };

  this.setState(state => {
    return {
      userValues: [...state.userValues, newdetails]
    }
  });
}

// or

addRow() {
  let newdetails = {
    name: "ManiVEL",
    age: 25,
    skill: "REACT JS"
  };

  this.setState({
      userValues: [...this.state.userValues, newdetails]
  });
}

编辑:您还需要直接使用道具,而不是将它们分配给子组件中的状态:

class CreateTablesam extends PureComponent {
  render() {
    const createRow = this.props.tabelDeatils.map((per, i) => (
      <tr key={i}>
        <td>{per.name}</td>
        <td>{per.age}</td>
        <td>{per.skill}</td>
      </tr>
    ));

    return (
      <div>
        <table>
          <thead>
            <tr>
              <td>Name</td>
              <td>Age</td>
              <td>skills</td>
            </tr>
          </thead>
          <tbody>{createRow}</tbody>
        </table>
        <button onClick={this.props.addtable}>CLICK</button>
      </div>
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.