React onClick event; updating the color (SOLVED)

React onClick event; updating the color (SOLVED)
0.0 0

#1

Hey there,

for learning purposes I wrote this class component. User should change the color everytime the buttons are clicked. The number hsl is gettig updated in the DOM, but the color is not changing. What did I do wrong?

class ColorShifter extends React.Component {
  constructor(props) {
    super(props)
    this.state = {hsl: 0};
    this.addHsl =this.addHsl.bind(this);
    this.reduceHsl=this.reduceHsl.bind(this);
    this.divStyle = {
      backgroundColor: `hsl(${this.state.hsl}, 100%, 50%)`
      } 
      this.addHsl = this.addHsl.bind(this);
      this.reduceHsl=this.reduceHsl.bind(this);    
  }
  addHsl() {
    this.setState({hsl: this.state.hsl +15})
  }
  reduceHsl() {
    this.setState({hsl: this.state.hsl -15})
  }
  render() {
    return (
      <div>
        <button onClick={this.addHsl}>Add HSL</button>        
        <button onClick={this.reduceHsl}>Reduce HSL</button>
        <p>{this.state.hsl}</p>
        <div id="square" style={this.divStyle}></div>
      </div>
    )
  }  
}

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

#2

I would try binding this inside the render function instead.

<button onClick={this.reduceHsl.bind(this)}>

I have used that before to avoid binding in the constructor

Also perhaps using ( ) around your setState object like so:

    this.setState({hsl: (this.state.hsl -15) })

#3

setState is asynchronous, so you can’t trust you’ll have the right value for this.state for it. You have to use the callback method in order to access the correct state.


#4

The only time you currently assign a value to this.divStyle is in the constructor. If you want this.divStyle to have a different value after the button clicks, you need to update it inside addHsl and reduceHsl also.


#5

@randelldawson thanks so much. I added this.divStyle to addHsl and reduceHsl and it works now!

addHsl() {
    this.setState({hsl: (this.state.hsl +15) })
    this.divStyle = {
      backgroundColor: `hsl(${this.state.hsl}, 100%, 50%)`
      } 
  }
  reduceHsl() {
    this.setState({hsl: (this.state.hsl -15) })
    this.divStyle = {
      backgroundColor: `hsl(${this.state.hsl}, 100%, 50%)`
      } 
  }