如何在React组件状态下拼接数组

时间:2019-06-01 06:18:29

标签: javascript node.js reactjs codesandbox

我正在制作时间表应用。 index.js呈现表。表的行是从子数组读取的。 children数组读取状态以保持自身更新。 AddRow()工作正常。 DeleteRow()有一些问题。我打算从事件中获取parentNode id,查找该状态的数组,对其进行拼接,然后让子级对其进行更新-这又将更新渲染。因此,当删除一行时,它将从状态数组中进行拼接,然后在子数组中对其进行更新,并依次进行渲染。 DeleteRow运行除array.splice或indexOf部分以外的所有内容。我什至尝试了for循环,但是没有用。我的方法正确吗?

index.js    
import React from "react";
import ReactDOM from "react-dom";
import HeaderAndFirstTableRow from "./headerandfirstrow";
import TableRow from "./tablerow";
import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { noOfRows: [] };
    this.addRow = this.addRow.bind(this);
    this.deleteRow = this.deleteRow.bind(this);
    this.find = this.find.bind(this);
  }
  addRow() {
    let arr = this.state.noOfRows;
    let arrLength = arr.length;
    arr.push(arrLength + 1);
    this.setState({
      noOfRows: arr
    });
  }
  find(arr, id) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i] === id) {
        return i;
      }
    }
  }
  deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let ix = arr.findIndex(id);
    arr.splice(ix, 1);
    this.setState({ noOfRows: arr });
  }
  render() {
    let children = [];
    for (let i = 0; i < this.state.noOfRows.length; i++) {
      children.push(
        <TableRow id={this.state.noOfRows.length} delete={this.deleteRow} />
      );
    }
    return (
      <HeaderAndFirstTableRow click={this.addRow}>
        {children}
      </HeaderAndFirstTableRow>
    );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

headerandfirstrow.js

import React from "react";

import "./styles.css";

export default function HeaderAndFirstTableRow(props) {
  function handler() {
    props.click();
  }
  return (
    <table>
      <tr>
        <th>Feature</th>
        <th>Phase</th>
        <th>Comments</th>
        <th>Monday</th>
        <th>Tuesday</th>
        <th>Wednesday</th>
        <th>Thursday</th>
        <th>Friday</th>
        <th>Saturday</th>
        <th>Sunday</th>
        <th onClick={handler}>+</th>
      </tr>

      {props.children}
    </table>
  );
}

tablerow.js
import React from "react";
import "./styles.css";
export default function TableRow(props) {
  function del(e) {
    props.delete(e);
  }
  return (
    <tr id={props.id}>
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td onClick={del}>-</td>
    </tr>
  );
}

3 个答案:

答案 0 :(得分:1)

splice改变了原始数组,你不应该改变状态,

您可以更改为此

deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let filteredArray = arr.filter(val=> val !== id)
    this.setState({ noOfRows: filteredArray });
}

答案 1 :(得分:0)

使用indexOf代替findIndex。 此外,请始终复制对象,而不是将其直接突变为状态。

这里正在处理小提琴: https://stackblitz.com/edit/react-6hfnww

答案 2 :(得分:0)

拼接this.state.noOfRows数组会改变其元素的位置。

deleteRows中,这将设置相同的数组,该数组现在会在组件状态下突变。

请改为使用Array.prototype.slice获取不包含项的数组块,并从中组成一个新数组。

  deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let ix = arr.findIndex(id);
    const noOfRows = [...arr.slice(0, ix), ...arr.slice(ix+1)] ;
    this.setState({ noOfRows });
  }