0

Running into errors with the circle component. this code renders a connect four board. the next step is to have the circle fill in when i click it. right now when i click a circle the first error is what is shown at the very top of the top below. Thanks so much in advance I am very new to React

TypeError: Cannot read property 'setState' of undefined
handleClick
C:/Users/james/connectFour/frontend/src/Circle.js:17
  14 | 
  15 |  handleClick(){
  16 |    let t = this;
> 17 |    t.setState((state, props) => ({
     | ^  18 |      ccc: !t.state.ccc
  19 |    }));
  20 |  }

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import Board from './Board.js';
import "bootstrap/dist/css/bootstrap.min.css";
import './index.css';


class Game extends React.Component{
  renderBoard(){
    return <Board/>;
  }

  render(){
    return(
      <div className="game">
        {this.renderBoard()}
        </div>
    )
  }
}

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

Board.js:

import React from 'react';
import Circle from './Circle.js';
import "bootstrap/dist/css/bootstrap.min.css";
import './index.css';


class Board extends React.Component {
  constructor(props){
    super(props);
  }
  renderCircle(){
    return <Circle/>;
  }
  render(){
    return (
        <div className="board">
          <div className="board-row">
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
          </div>
          <div className="board-row">
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
          </div>
          <div className="board-row">
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
          </div>
          <div className="board-row">
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
          </div>
          <div className="board-row">
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
          </div>
          <div className="board-row">
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
            {this.renderCircle()}
          </div>
        </div>
      )
  };
}

export default Board;

Circle.js:

import React from 'react';
import "bootstrap/dist/css/bootstrap.min.css";
import './index.css';


class Circle extends React.Component {
  constructor(props) {
    //let t = this;
    super(props);
    this.state = {
      ccc: true,
    };
  }

  handleClick(){
    let t = this;
    t.setState((state, props) => ({
      ccc: !t.state.ccc
    }));
  }

  render() {
    return (
      <button className="square">
        <button className={this.state.ccc ? "circle": "circleFilled"} onClick={this.handleClick}></button>        
      </button>
    );
  }
}

export default Circle;
James
  • 5
  • 3

2 Answers2

0

Didn't read all the code but I think you should try :

handleClick(){
    this.setState({
    ccc: !this.state.ccc
});}

Should work fine

Mikycid
  • 91
  • 1
  • 1
  • 4
  • this is what i originally tried but I ran into the same problem. the solution by @D10S works – James Jun 04 '20 at 18:36
0

The problem is that "t" receives the "this" of the "handleClick" function instead of the "Circle" class. This is exactly what 'binding' is for.

    import React from 'react';
    import "bootstrap/dist/css/bootstrap.min.css";
    import './index.css';


    class Circle extends React.Component {
      constructor(props) {
        //let t = this;
        super(props);
        this.state = {
          ccc: true,
        };
        this.handleClick = this.handleClick.bind(this);   // <--- The addition
      }

      handleClick(){
        let t = this;
        t.setState((state, props) => ({
          ccc: !t.state.ccc
        }));
      }

      render() {
        return (
          <button className="square">
            <button className={this.state.ccc ? "circle": "circleFilled"} onClick={this.handleClick}></button>        
          </button>
        );
      }
    }

    export default Circle;
D10S
  • 1,468
  • 2
  • 7
  • 13