React, Random Color Change

React, Random Color Change
0

#1

Hello, FreeCodeCamp users.

I have been working on my first exercise to build an app. The main code is from Codecademy (Color Picker from React101 course).

I have modified the random button. The original code uses one button to generate new color entirely. I have modified it to 4 button to generate separate color component RGBA.

I want to ask something. Could we use only one handleClick to simplify the code? Until right now, the code is one handleClick for one <Button /> so I need 4 handleClicks method.

Iā€™m also looking for some other suggestions for the code to be cleaner and better organized, or maybe some idea to further develop the code.

Iā€™m sorry if my choice of words a bit awkward. Thank you.

import React from 'react';
import './App.css';

class Button extends React.Component {
	render() {
		return (
			<button onClick={this.props.onClick} 
				className={ this.props.light ? 'light-button' : 'dark-button' }
				test={this.props.text}
				>
				{this.props.text}
			</button>
		);
    }
    
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      red: 10,
      green: 72,
      blue: 129,
      alpha: 1.0,
      test: ''
    };
    this.handleRedClick = this.handleRedClick.bind(this);
    this.handleGreenClick = this.handleGreenClick.bind(this);
    this.handleBlueClick = this.handleBlueClick.bind(this);
    this.handleAlphaClick = this.handleAlphaClick.bind(this);
  }
  componentDidMount() {
    this.applyColor();
  }

  componentDidUpdate(prevProps, prevState) {
    this.applyColor();
  }

  formatColor(r, g, b, a) {
    return `rgba(${r}, ${g}, ${b}, ${a})`;
  }

  isLight() {
    const rgb = +this.state.red + +this.state.green + +this.state.blue;
    return rgb < (127 * 3);
  }

  applyColor() {
    const color = this.formatColor(this.state.red, this.state.green, this.state.blue, this.state.alpha);
    document.body.style.background = color;
  }

  randomizeValue() {
    let random = 0;
    random = Math.floor(Math.random()*256);
    return random;
  }
  
  handleRedClick() {
    this.setState({ red: this.randomizeValue() });
  }
  handleGreenClick() {
    this.setState({ green: this.randomizeValue() });
  }
  handleBlueClick() {
    this.setState({ blue: this.randomizeValue() });
  }
  handleAlphaClick() {
    this.setState({ alpha: (this.randomizeValue() / 256).toFixed(2)});
  }

  render() {
    return (
      <div>
        <h1 className={this.isLight() ? 'white' : 'black'}>
					Your color is {this.formatColor(this.state.red, this.state.green, this.state.blue, this.state.alpha)}.
        </h1>
        <div className="col">
          <Button text="Random Red" light={this.isLight()} onClick={this.handleRedClick} />
          <Button text="Random Green" light={this.isLight()} onClick={this.handleGreenClick} />
          <Button text="Random Blue" light={this.isLight()} onClick={this.handleBlueClick} />
          <Button text="Random Alpha" light={this.isLight()} onClick={this.handleAlphaClick} />
        </div>
        
        <p>
        </p>
      </div>
    );
  }
}

export default App;

Edit:
This is the screenshot of the simple app.


#2

Hi,

You can use something like this:

handleClick(value) {
  this.setState({
    [value]: value === 'alpha'
      ? (this.randomizeValue() / 256).toFixed(2)
      : this.randomizeValue();
  });
} 

#3

Your example above forced me to learn something new today regarding how to dynamically set a key/value on a object. For anyone interested in learning more about how [value] : value works, see the Medium below.

@SpaniardDev Thanks for the valuable insight. I will definitely be using this in the future when I can.


#4

One is glad to be of service. :slight_smile:


#5

Wow. Thank you. After implementing suggestion from @SpaniardDev, reading link provided by @RandellDawson, and reading how to pass parameter to event handler, finally I can use only one handleClick to all of the random button.

Edit:
Next I want to add input and submit button to change the color that user like. Then the text color will be the inversion of background color.