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

How to splice an array within the state of a React Component

我正在制作一个时间表应用程序。 index.js 呈现 table。 table 的行是从 children 数组中读取的。 children 数组读取状态以保持自身更新。 AddRow() 工作正常。 DeleteRow() 有一些问题。我打算从事件中获取 parentNode id,查找状态数组,拼接它并让 children 更新自身 - 这反过来会更新渲染。所以当一行被删除时,它是从状态数组中拼接出来的,然后在 children 数组中更新,然后渲染。 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>
  );
}

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

使用 indexOf 而不是 findIndex。 此外,始终复制对象而不是将它们直接变异到状态中。

这里正在工作Fiddle: https://stackblitz.com/edit/react-6hfnww

拼接 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 });
  }