背景故事

注意:此问题是对T.J. Crowder提供的答案here的扩展。

我通过创建一个保存行数组的状态对此进行了扩展,以便可以使用setState更新该数组(从中删除)。

我添加了一个handleClick函数来处理我希望用户能够根据所单击元素的索引对数组执行的操作。 (当前所包含的只是右键单击从数组中删除目标索引。

/rowList.js

import React, { Component } from "react";
import Row0 from "./../rows/row0";
import Row1 from "./../rows/row1";
import Row2 from "./../rows/row2";
import Row3 from "./../rows/row3";

const row0 = () => <Row0 />;
const row1 = () => <Row1 />;
const row2 = () => <Row2 />;
const row3 = () => <Row3 />;
class RowInfo {
  static id = 0;
  constructor(Comp) {
    this.Comp = Comp;
    this.id = RowInfo.id++;
  }
}
class RowList extends Component {
  constructor() {
    super();
    this.state = {
      rows: [
        new RowInfo(row0),
        new RowInfo(row1),
        new RowInfo(row2),
        new RowInfo(row3)
      ]
    };
  }
  handleClick = (a, b) => e => {
    e.preventDefault();
    if (e.nativeEvent.which === 1) {
      //left click
      console.log(a); //for testing
      console.log(b); //for testing
    } else if (e.nativeEvent.which === 3) {
      //right click
      this.setState({
        rows: this.state.rows.filter((_, i) => i !== a)
      });
    }
  };

  render() {
    return (
      <>
        {this.state.rows.map(({ id, Comp }) => (
          <tr
            key={id}
            onClick={this.handleClick(id)}
            onContextMenu={this.handleClick(id)}
          >
            <Comp />
          </tr>
        ))}
      </>
    );
  }
}
export default RowList;


然后,我测试了两次调用<RowList />组件的过程,以便可以测试删除两个组件中的行。

注意:Mod0导入到/main.js文件中,该文件又导入到/index.js中,并在<div id="root"></div>中呈现为index.html

/mod0.js

import React, { Component } from "react";
import RowList from "./../rows/rowList";
class Mod0 extends Component {
  render() {
    return (
      <>
        <table>
          <tbody>
            <RowList />
          </tbody>
        </table>
        <table>
          <tbody>
            <RowList />
          </tbody>
        </table>
      </>
    );
  }
}




问题

在测试清除效果时,我意识到了一个关键错误,根据我目前的知识,该错误的性质只能使我相对确定,因此我的解释可能不准确/有缺陷。似乎我只能从<RowList />中呈现的前4行中删除,因为后4行不会腐蚀this.state.rows中的数组。

我认为解决方案是基于原始状态数组和调用<RowList />的次数构建一个新数组。并渲染该数组。

也许我可以更新状态,如下所示:

constructor() {
    super();
    this.state = {
      rows: [
        new RowInfo(row0),
        new RowInfo(row1),
        new RowInfo(row2),
        new RowInfo(row3)
      ],
      rendRows: this.rendRowsTemp
    };
    this.rendRowsTemp = []; //push to build a new array into here?
  }


然后像这样使用新数组:

  render() {
    return (
      <>
        {this.state.newRows.map(({ id, Comp }) => (
          <tr
            key={id}
            onClick={this.handleClick(id)}
            onContextMenu={this.handleClick(id)}
          >
            <Comp />
          </tr>
        ))}
      </>
    );
  }




预期结果

我需要一种基于原始状态数组和调用<RowList />的次数构建新数组的方法。

最佳答案

我认为问题在于,在过滤器的条件(this.state.rows.filter((_, i) => i !== a))中,您正在数组中使用RowInfo的索引而不是ID,请尝试:this.state.rows.filter(({ id }) => id !== a)

10-06 01:32