2

I got rendered array of filters, by clicking on element I'm pushing them to selectedProperties array, and also I want to set active class on element if it in array. How to do it properly with react? I got next code

...
render(){
  const {selectedProperties} = this.state;
  let classnames = classNames('box', {
    'active': '' //what condition apply here to set class?
  });
return (
  <div className="hotel-filter">
    <div className="filter-label">Что для вас важно?</div>
    <div className="filter-options">
      <ul className="priorities-boxes">
        {
          this.state.priorities.map(item => {
            return (
              <li key={item.id}
                  className={classnames}
                  onClick={(evt) => this.selectValue(item.id)}>
                <img src={`/images/filter-icons/${item.icon}`} />
                <span>{item.name}</span>
              </li>
            )
          })
        }
      </ul>
    </div>
  </div>
)
}

I'm using classnames utility to add class dynamically but my condition is wrong.

2
  • On your let classnames, item.id is not defined? Commented Dec 14, 2017 at 11:25
  • yes. and actually I don't know what condition apply there Commented Dec 14, 2017 at 11:27

3 Answers 3

2

You need the reference to item in order to check it is in the selected array, which cannot be done outside the loop, otherwise all would be the same, so just do it inside the loop instead for each item

render(){
  const {selectedProperties} = this.state
  return (
    <div className="hotel-filter">
      <div className="filter-label">Что для вас важно?</div>
      <div className="filter-options">
        <ul className="priorities-boxes">
          {
            this.state.priorities.map(item => {
              return (
                <li key={item.id}
                    className={classNames('box', {
                      active: selectedProperties.includes(item.id)
                    })}
                    onClick={(evt) => this.selectValue(item.id)}>
                  <img src={`/images/filter-icons/${item.icon}`} />
                  <span>{item.name}</span>
                </li>
              )
            })
          }
        </ul>
      </div>
    </div>
  )
}
Sign up to request clarification or add additional context in comments.

4 Comments

Tried just now, not helped. I click on element and nothing changed. (
Well this will work as long as this.selectValue is actually updating the selectedProperties array. You don't show that so we can't diagnose
you right, I forget to call setState after push in array.
great glad its fixed!
2

This might resolve issue with multiple element class toggling.try this out:

https://jsfiddle.net/menomanabdulla/todu7m6g/11/

class ToggoleApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    
    }
    
    this.toggleClass=this.toggleClass.bind(this);
    
  }
  
   toggleClass(e){
        let classes = 'my-class';
        let els = document.getElementsByClassName('my-class active');
        if(els){
            while (els[0]) {
                els[0].classList.remove('active')
            }
        }
        e.target.className = classes.replace('my-class','my-class active');
    }
  
  render() {
    return (
      <div>
        <h2>Toggle Example</h2>
        <ul>
          <li className="my-class active" onClick={(e) =>this.toggleClass(e)}>
            One
          </li>
          <li className="my-class" onClick={(e) =>this.toggleClass(e)}>
            Two
          </li>
          <li className="my-class" onClick={(e) =>this.toggleClass(e)}>
            Three
          </li>
        </ul>
      </div>
    )
  }
}

ReactDOM.render(<ToggoleApp />, document.querySelector("#app"))
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

.my-class{
  color: #FF3355;
}
.my-class.active{
  color: #33FF46;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

2 Comments

one doubt why we are using while loop? even without it, its working fine for me.
umm! what about remove active class from previous elements? while is play main role as toggling here.
0

class ToggoleApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    
    }
    
    this.toggleClass=this.toggleClass.bind(this);
    
  }
  
   toggleClass(e){
        let els = document.getElementsByClassName('my-class active');
        if(els){
            while (els[0]) {
                els[0].classList.remove('active')
            }
        }
        e.target.className = 'my-class active'
    }
  
  render() {
    return (
      <div>
        <h2>Toggle Example</h2>
        <ul>
          <li className="my-class active" onClick={(e) =>this.toggleClass(e)}>
            One
          </li>
          <li className="my-class" onClick={(e) =>this.toggleClass(e)}>
            Two
          </li>
          <li className="my-class" onClick={(e) =>this.toggleClass(e)}>
            Three
          </li>
        </ul>
      </div>
    )
  }
}

ReactDOM.render(<ToggoleApp />, document.querySelector("#app"))

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.