Создать новый массив из существующего массива на основе количества вызовов компонентов - PullRequest
2 голосов
/ 11 июля 2019

Предыстория

Примечание. Этот вопрос является дополнением к ответу T.J. Crowder при условии здесь .

Я расширил это, создав состояние для хранения массива строк, чтобы я мог обновить массив (удалить из), используя 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>
      </>
    );
  }
}


Проблема

При тестировании удаления я обнаружил критическую ошибку, характер которой мои нынешние знания могут только сделать меня относительно уверенным, поэтому мое объяснение может быть неточным / ошибочным. Казалось бы, я могу удалить только из первых 4 строк, которые отображаются в <RowList />, так как вторые 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 />.

1 Ответ

1 голос
/ 11 июля 2019

Мне кажется, проблема в том, что в состоянии фильтра (this.state.rows.filter((_, i) => i !== a)) вы используете индекс RowInfo в массиве, а не его идентификатор, попробуйте: this.state.rows.filter(({ id }) => id !== a)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...