0

I have a 2d array of integers, each of which are being mapped to a render method that displays each value as a button. What I am trying to do is when the user clicks on the button, it updates the index of the elements, so it will show the updated value when the button is being rendered. However, the onClick method is never being called.

class Matrix extends Component {
  state = {
    rows: 0,
    cols: 0,
    elements: null
  };

  constructor() {
    super();
    this.state.elements = this.createMatrix();
  }

  updateElements = (i, j) => {
    console.log("CLICK");
    const newElements = this.state.elements.slice();
    newElements[i][j]++;
    this.setState({ elements: newElements });
    console.log(this.state.elements[i][j]);
  };

  render() {
    return (
      <div>
        <table>
          <tbody>
            {Object(
              this.state.elements.map((e, i) => {
                return (
                  <tr>
                    {Object(
                      e.map((f, j) => {
                        return (
                          <td>
                            <MatrixElement
                              onClick={() => this.updateElements(i, j)}
                              value={f}
                            />
                          </td>
                        );
                      })
                    )}
                  </tr>
                );
              })
            )}
          </tbody>
        </table>
      </div>
    );
  }
  createMatrix = () => {
    var matrix = [];
    var i, j;
    var sub;
    for (i = 0; i < this.state.rows; i++) {
      sub = [];
      for (j = 0; j < this.state.cols; j++) {
        sub[j] = 0;
      }
      matrix[i] = sub;
    }
    return matrix;
  };
}



class MatrixElement extends Component {
  render() {
    return <button>{this.props.value}</button>;
  }
}

If I change the onClick method to this:

onClick={this.updateElements(i, j)}

I get overflow errors. I imagine there is a much simpler way to implement what it is I'm trying to do, but I don't understand why this doesn't work.

3
  • Can you provide more code? A runnable/reproducible CodeSandbox would get you an answer very quickly. Commented Nov 17, 2019 at 3:19
  • onClick doesn’t receive I, j; it receives the synthetic event. You can’t make up parameters. Commented Nov 17, 2019 at 3:19
  • added more code Commented Nov 17, 2019 at 3:34

2 Answers 2

3

You likely mean to not pass any parameters to the onClick handler:

onClick={() => this.updateElements(i, j)}

As you're relying on i and j from your iterators outside of that function.

Edit: You also need to handle the onClick in your Matrix element!

class MatrixElement extends Component {
  render() {
    return <button onClick={this.props.onClick}>{this.props.value}</button>;
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

changed it to this but it still doesn't fire
Ah-ha, updated to make sure you're actually firing the click event!
Glad to hear it, happy coding!
0

You've declared your onClick to accept two parameters, i and j, but React doesn't pass your variables to the function, it passes the synthetic event. i and j are already in scope at that point of the code, so there's no reason to add extra parameters to your function.

Try changing your onClick to

() => this.updateElements(i, j)

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.