1

What I need to do is render each of my 4 (!)Bumper at different times from one another in sequence. I'm trying to pass an array through the method (!)simClicks() which updates setState inside a for loop ('I know, it's disgusting code. Not sure how else to asynchronously batch udpate child components'). Obviously React don't do dat. Any time I pass an array into (!)simClicks(lightOrder), all child elements light up at the same time. I want them to light up in order, one after another, after a delayed period from one another.

class Board extends React.Component{
  constructor(props){
    super(props)
    this.state ={
      on: false,
      count: 0,
      computer: [],
      history: [],
      3:"0",
      2:"0",
      1:"0",
      0:"0"
    }
  } 

  SimClicks(lightOrder){
    console.log(lightOrder)
    for(i=0; i<lightOrder.length; i++){
        let newString = this.state[lightOrder[i]] + i.toString()
        this.setState({[lightOrder[i]]: newString})   
    }
  }

  Start(){
    //if(this.state.on === false){
      let computer = [],
          history = [],
          state = this.state.on,
          swich = state == true ? false : true,
          rando = Math.floor(Math.random() * 4)
      computer.push(rando)
      this.setState({on: swich, history: history, computer: computer})
      this.SimClicks(computer)
   // }
  }
  handleClicks(number){
    if(this.state.on == true){
      let arr = this.state.history
      arr.push(number)
      this.setState({history: arr})
    }
  }

  Bumper(lights, color, rotate, number){
    if(this.state.on == true){
      return <Bumper lights={lights} backgroundColor={color} transform={rotate} number={number} onClick={() => this.handleClicks(number)} ai={this.state[number]}/>
    }else{
      return <Bumper lights={color} backgroundColor={color} transform={rotate} number={number}/>
    }
  }

  render(signals){
    const styles = {
      height: '86vh',
      width: '86vh',
      backgroundColor: 'black',
      borderRadius: '86vh',
      margin: 'auto',
      marginTop: '8vh',
      overflow: 'auto',
      border: 'none',
      boxShadow: '10px 0px 20px 1px'
    }

    return(
      <div style={styles}>
        {this.Bumper('#FFcce0','#FF0099','rotate(180deg)',3)}
        {this.Bumper('#ffFFFF','#00FFFF','rotate(270deg)',0)}
        {this.Bumper('#B3FFB3','#00FF00','rotate(90deg)',2)}
        {this.Bumper('#FFFFE0','#FFFF00','rotate(0deg)',1)}
        <Start onClick={() => this.Start()} />
        <Counter count={this.state.count} />
      </div>
    )
  }
}

class Bumper extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      lights: false,
      change: "0"
    }
  }
  componentWillReceiveProps(){
    if(this.props.ai && this.props.ai != this.state.change){
      let set = this.props.ai
      this.LightsOn()
      this.setState({change: set})
    }
  }
  LightsOn(){
    this.setState({lights: true})
    setTimeout(function(){
      this.setState({lights: false})
    }.bind(this), 200)
  }

  handleClick(){
    this.LightsOn()
    this.props.onClick()
  }
  render(){
    const style = {
      backgroundColor: this.state.lights === true ? this.props.lights : this.props.backgroundColor,
      transform: this.props.transform,
      height: '40vh',
      width: '40vh',
      borderBottomRightRadius: '40vh',
      float: 'left',
      display: 'flex',
      flexWrap: 'wrap',
      cursor: 'pointer'
    }

    return(
      <div style={style} onClick={() => this.handleClick()} />
    )
  }
}
class Start extends React.Component{
  render(){
    const style = {
      height: '10vh',
      width: '20vh',
      position: 'absolute',
      backgroundColor: '#008000',
      borderRadius: '10px',
      fontSize: '6vh',
      lineHeight: '1',
      color: 'black',
      textAlign: 'center',
      fontFamily: 'Supermercado One',
      cursor: 'pointer',
      boxShadow: '0px 4px 26px 0px'
    }
    return(<button style={style} onClick={this.props.onClick}>Start!</button>)
  }
}

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

I'm not looking for this code to be fixed necessarily. More or less just a way to update child components separately, in a specified order.

1
  • React batches together subsequent calls to setState(). Try using setTimeout() between setState calls Commented Feb 6, 2018 at 6:50

1 Answer 1

1

setState takes a second callback argument to inform you the state is updated. You can use it to create the behaviour you described. Please do not use setTimeout as Dane described. This could lead to unexpected behaviour.

this.setState({foo:'bar'},()=> {
   assert this.state.foo === 'bar';
});
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.