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

Community
  • 1
  • 1
Matty
  • 277
  • 5
  • 17

1 Answers1

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.

azium
  • 20,056
  • 7
  • 57
  • 79
  • Thanks. Can I replace `defaultStyle` with a className or with ' ' to default to the className? – Matty Oct 24 '16 at 23:52
  • `style` needs an object, which can be empty. so not empty string but empty object `this.state.clickedDiv === 'div1 ? clickedStyle : {}` – azium Oct 24 '16 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 Oct 25 '16 at 01: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 Oct 25 '16 at 01: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 Oct 25 '16 at 04:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126672/discussion-between-matty-and-azium). – Matty Oct 25 '16 at 22:18