【问题标题】:Build new array from existing array based on number of component calls根据组件调用的数量从现有数组构建新数组
【发布时间】:2019-11-21 02:00:37
【问题描述】:

背景故事

注意:此问题是对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;

然后我测试了两次调用&lt;RowList /&gt; 组件,以便我可以测试跨两个组件删除行。

注意:Mod0 被导入到 /main.js 文件中,该文件被导入到 /index.js 中,在 index.html 中被渲染到 &lt;div id="root"&gt;&lt;/div&gt;

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


问题

在测试删除时,我意识到一个关键错误,我目前的知识只能让我相对确定其性质,因此我的解释可能不准确/有缺陷。看来我只能从&lt;RowList /&gt; 中呈现的前 4 行中删除,因为后 4 行不对应于this.state.rows 中的数组。

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

也许我可以更新状态,开始时可能看起来像这样:

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


预期结果

我需要一个方法来基于原始状态数组和调用&lt;RowList /&gt; 的次数来构建新数组。

【问题讨论】:

  • 我认为问题是在过滤器的条件下 (this.state.rows.filter((_, i) =&gt; i !== a)) 你在数组中使用RowInfo 的索引而不是它的 ID,试试:this.state.rows.filter(({ id }) =&gt; id !== a)
  • 你能解释一下当你点击 2nd RowList 中的某一行时会发生什么吗?
  • @Titus 谢谢!一切都解决了,你应该把它作为答案发布,这样我就可以打勾了

标签: javascript arrays reactjs ecmascript-6


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2015-02-18
    • 2019-05-05
    • 1970-01-01
    • 2021-03-09
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    相关资源
    最近更新 更多