简体   繁体   中英

Checkerboard Component Lifecycle

I am trying to create a checkerboard that resizes given an integer as an input and returns a int by int checkerboard as an output. Currently, my checkerboard renders from a set variable in state which is 8 by default, but every time I try to add my input, the app crashes. I am trying to find a way to understand my component's lifecycle more effectively. Below is the code for my checkerboard component.

import React, { Component } from 'react'


class Checkerboard extends Component {

  constructor(props) {
    super(props)
    this.state = {
      checkers: [],
      size: 8,
      input: null
    }
    this.handleSubmit = this.handleSubmit.bind(this)
    this.handleChange = this.handleSubmit.bind(this)
  }


  // This function divides the squares from state into rows and draws the board
  drawBoard = (squares) => {
    console.log("drawBoard running...")
    console.log("drawing board from state:", squares)
    let rows = []
    for (let i=0; i<squares.length; i+=this.state.size) {
      rows.push(squares.slice(i,i+this.state.size));
    }
    console.log("Rows: ", rows)
    return (rows.map(row => (
      <div className="row" style = {{ display: 'flex' }}>
        {row.map(square =>(
          <div className="square" key = {square.key} style = {{
            backgroundColor: `${square.color}`,
            height: '50px',
            width: '50px',
            margin: '0 auto',
            display: 'inline-block',
          }}>
          </div>
        ))}
      </div>
    )))
  }


  addSquares = (col) => {
    console.log("adding squares...")
    let squares = []
    for (let i=0; i<(col ** 2); i++) {
      if ((((Math.floor(i/this.state.size)+1)%2))!== 0){
        if (((i-((Math.floor(i/this.state.size))*col)+1)%2) !==0){
          squares.push( { key: i, row: Math.floor(i/this.state.size), column: i-((Math.floor(i/this.state.size))*col), color: "white" } )
          continue
        } else {
          squares.push( { key: i, row: Math.floor(i/this.state.size), column: i-((Math.floor(i/this.state.size))*col), color: "black" } )
          continue
        } 
      }
      else if (((Math.floor(i/this.state.size)+1)%2) === 0) {
        if (((i-((Math.floor(i/this.state.size))*col)+1)%2) !==0){
          squares.push( { key: i, row: Math.floor(i/this.state.size), column: i-((Math.floor(i/this.state.size))*col), color: "black" } )
          continue
        } else {
          squares.push( { key: i, row: Math.floor(i/this.state.size), column: i-((Math.floor(i/this.state.size))*col), color: "white" } )
          continue
        }
      }
    }
    console.log(squares)
    return this.setState({ checkers: squares })
  }

  componentDidMount() {
    this.addSquares(this.state.size)
  }

  handleChange(event) {
    this.setState({ input: event.target.value})
  }

  handleSubmit(event) {
    event.preventDefault()
    this.setState({ size: this.state.input})
    console.log(this.state.size)
  }


  render() {
    return (
      <div className="checkerBoard" style={{overflow: 'hidden'}}>
        {this.drawBoard(this.state.checkers)}
        <form onSubmit={this.handleSubmit}>
          <input placeholder="Enter desired dimensions" type="integer" onChange={this.handleChange}></input>
          <button type="submit">Submit</button>
        </form>
      </div>
    )   
  }

}
export default Checkerboard;

"...I am trying to find a way to understand my component's lifecycle more effectively..."

I've read your code ( without going through the math in addSquares() ), and to your lifecycle's understanding, I see this pattern:

  1. Component mounts
  2. state loads
  3. addSquares() is called by componentDidMount() , given a state value
  4. Your component is now waiting for your response as a user.
  5. You set a number, thereby you change state once, causing a render.
  6. You click submit, thereby changing state again, causing another render.
  7. Your app crashes!

I hope I got that right, and if so, I can think of one reason why it mat crash: Your squares never re-render because the only thing defining them is componentDidMount() , which, as its name, is called only when mounted (once). You can use componentDidUpdate() to call addSquares() again.

I played with your code a bit. When I was changing stuff up I kept having the handleSubmit function run, so it made me think there was an issue with your bind statement up top.

I like the idea of creating a sized checkerboard. Not really an answer to what was wrong, but ended up doing a refactor with hooks if you want to check it out.

https://codesandbox.io/s/sweet-hellman-u4gvf?file=/src/App.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM