1

Below I have one component that seems to work fine except that when I click on one of the div's all the div's change. I can't seem to figure out if I need to add a key, ref, or index element. I have tried all three to no avail. I think the ES6 is throwing me off. So essentially, I am looking to change the color of only the div that is clicked on.

  import React from 'react';
    class AwesomeComponent2 extends React.Component {
      constructor(props){
        super(props);
        this.state = {
          onClicked: false
        }
        this.handlerButtonOnClick = this.handlerButtonOnClick.bind(this);
      }
      handlerButtonOnClick(event){
        alert(event.target);
        this.setState({
           onClicked: true
        });
      }
      render() {
        var _style;
        if (this.state.onClicked){ // clicked button style
          _style = {
              backgroundColor: "#FAE456"

            }

        }
        else{ // default button style
          _style = {
              backgroundColor: "#B3B3B3"
            }
        }
        return (
            <div className="main-container">
            <div onClick={this.handlerButtonOnClick}
                    style={_style} className ="nineBoxes"> </div>
            <div onClick={this.handlerButtonOnClick}
                    style={_style} className ="nineBoxes" className="nineBoxes"> </div>
            <div onClick={this.handlerButtonOnClick}
                    style={_style} className ="nineBoxes" className="nineBoxes"> </div>
          </div>
        );
      }
    }

The link below didn't clarify this issue for me.

Getting Index of onClick target with ReactJs

0

1 Answer 1

1

You can pass arguments to your onClick functions.

<div onClick={() => this.handlerButtonOnClick('div1')}>

Save that value in state:

handlerButtonOnClick(div) {
  this.setState({
    clickedDiv: div
  });
}

Then conditionally apply that style in render

<div style={this.state.clickedDiv === 'div1' ? clickedStyle : defaultStyle}>

Update:

Let's say instead of keeping track of just one clicked item, you would like to be able to click items on and off, essentially toggling them into and out of an array.

Your onClick function doesn't need to change, but your handler logic does:

handlerButtonOnClick(div) {
  let resultingArray = [];
  // check if the div is already in your state array
  if (this.state.clickedDivs.includes(div)) {
    // if it is, filter it out
    resultingArray = this.state.clickedDivs.filter(d => d !== div)
  } else {
    // if it isn't, concatenate your state array with the new div
    resultingArray = this.state.clickedDivs.concat(div)
  }

  this.setState({
    clickedDivs: resultingArray
  });
}

Now clicking a div will add or remove itself from the clicked state and you can check if it's in the array to apply the style.

<div style={this.state.clickedDivs.includes('div1') ? clickedStyle : defaultStyle}>

As mentioned in your comment, defaultStyle can be an empty object if you want.

6
  • Thanks. Can I replace defaultStyle with a className or with ' ' to default to the className?
    – Matty
    Commented Oct 24, 2016 at 23:52
  • style needs an object, which can be empty. so not empty string but empty object this.state.clickedDiv === 'div1 ? clickedStyle : {}
    – azium
    Commented Oct 24, 2016 at 23:58
  • Yes, the original problem is solved. Do I need to add a new function to make it keep the onclick color remain after I click another div?
    – Matty
    Commented Oct 25, 2016 at 1:27
  • 1
    No, you would just need to modify your function to keep an array of div ids vs a single value. Then check if the value is in that array to determine the style
    – azium
    Commented Oct 25, 2016 at 1:41
  • on second look, I can't seem to understand how to go about this improvement. If I stick the array inside the handleClick function, it updates the contents of the array each time. handlerButtonOnClick(div){ this.setState({ clickedDiv: div }); this.setState({ onClicked: true, }); } I tried passing through an arr = [div], clickedDiv = arr but that doesn't work
    – Matty
    Commented Oct 25, 2016 at 4:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.