1

I am trying to create a component where I have a bunch of boxes from an array, that can be turned 'on' and 'off' when each one is individually clicked.

Currently, only a single item from the array can be switched 'on' (shown by the item turning green), however, I would like to be able to turn each item on/off individually.

Interacting with one element should not affect any of the others.

How do I achieve this?

My click event:

  handleOnClick = (val, i) => {
    this.setState({active: i}, () => console.log(this.state.active, 'active'))
  }

Rendering the boxes:

 renderBoxes = () => {

    const options = this.state.needsOptions.map((val, i) => {
        return (
          <button
            key={i}
            style={{...style.box, background: i === this.state.active ? 'green' : ''}}
            onClick={() => this.handleOnClick(val, i)}
          >
            {val}
          </button>
        )
      })

      return options

  }

Here's a Codepen

1
  • 1
    To store the state of a bunch of boxes you need an array of bools, like [true, false, false]. You currently have a single variable storing an index instead. Commented Mar 27, 2019 at 21:45

1 Answer 1

1

What I would do is to create a Box component with its own active state, and pass this to the map in renderBoxes. The benefit of doing it this way is that each Box component will have its own state independent of the parent. That way you can have more than one component as active.

so...

class Box extends React.Component {
  constructor(props){
    super(props)
    this.state={
      active: false
    }
  }

  clickHandler = () => {
    this.setState({active: !this.state.active})
  }

  render(){
    const { key, children }= this.props
    return (
      <button
            key={key}
            style={{...style.box, background:     this.state.active ? 'green' : ''}}
            onClick={() => this.clickHandler()}
          >
            {children}
          </button>
    )
  }
}

then have renderBoxes be...

renderBoxes = () => {

    const options = this.state.needsOptions.map((val, i) => {
        return (
          <Box
            key={i}
          >
            {val}
          </Box>
        )
      })

      return options

  }

here is the codepen I forked off yours.

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.