2

Backstory

Note: This question is an expansion to the answer T.J. Crowder provided here.

I expanded on this by creating a state to hold the rows array so that I could update the array (remove from) using setState.

I added a handleClick function to handle what I would like the user to be able to do to the array based on the index of the element being clicked. (currently all that is included is that right click removes the target index from the array.

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

I then tested calling the <RowList /> component twice so that I can test removing rows across two components.

Note: Mod0 is imported into a /main.js file which is imported to /index.js which is rendered to <div id="root"></div> in 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>
      </>
    );
  }
}


Problem

When testing the removal I realised a crucial error, the nature of which my current knowledge can only make me relatively certain of so my explanation may be innacurate/flawed. It would seem I can only remove from the first 4 rows that are rendered in <RowList /> as the second 4 rows do not corrospond to the array in this.state.rows.

I think the solution is to build a new array based on the original state array and the amount of times <RowList /> is called. And render that array instead.

Perhaps I could update the state could look something like this to begin with:

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?
  }

And then use the new array instead like so:

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


Expected Result

I need a method to build the new array based on the original state array and the amount of times <RowList /> is called.

3
  • 1
    I think the problem is that in the filter's condition (this.state.rows.filter((_, i) => i !== a)) you're using the RowInfo's index in the array not it's ID, try: this.state.rows.filter(({ id }) => id !== a) Commented Jul 11, 2019 at 11:05
  • Can you explain exactly what happens when you click on one of the rows in the 2nd RowList? Commented Jul 11, 2019 at 11:08
  • @Titus Thank you! That's fixed everything, You should post it as the answer so I can tick it Commented Jul 11, 2019 at 11:53

1 Answer 1

1

I think the problem is that in the filter's condition (this.state.rows.filter((_, i) => i !== a)) you're using the RowInfo's index in the array not it's ID, try: this.state.rows.filter(({ id }) => id !== a)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.