2

I have React component, with state managed by redux, ul list and a css-class. I want to apply class to one of li elements, depending on state. For instance, if myStateProp = a, apply css class to first li, if myStateProp = b, apply class to second li and so on. But I'm not sure how to do it properly.

For now I solved this problem like this:

<ul>
    <li className={this.props.myStateProp ==="a" ? "myCssClass" : ""}>A</li>
    <li className={this.props.myStateProp ==="b" ? "myCssClass" : ""}>B</li>
    <li className={this.props.myStateProp ==="c" ? "myCssClass" : ""}>C</li>
</ul>

But I don’t really like this approach, seems too many copied code. Maybe there is a way to do it more neatly?

8
  • 1
    Looks like a valid solution Commented Nov 29, 2018 at 12:44
  • I don't see how you could do it any other way, unless you had the values of the li in a var and then did a loop Commented Nov 29, 2018 at 12:45
  • Oh, I see. I'll stick to this solution then. Thanks for verification Commented Nov 29, 2018 at 13:05
  • You can try classnames Commented Nov 29, 2018 at 13:23
  • Maybe it would help if you give us a bit more code/context. There are always many possible solutions. Some more, some less elegant. From your code it looks like you are assigning the class according to the click or some similar event. If that's the case, you can maybe have some handleClick(e) function which will assign the class on e.target. It's really hard to tell without proper context. Commented Nov 29, 2018 at 14:23

2 Answers 2

3

While there's nothing inherently wrong with your code, you could simplify it with a class method ternary statement and return "myCssClass" or null.

class Example extends PureComponent {

  isActive = item => this.props.someProp === item ? "myCssClass" : null  

  render = () => (
    <ul>
      <li className={isActive("a")}>A</li>
      <li className={isActive("b")}>B</li>
      <li className={isActive("c")}>C</li>
    </ul>
  )
}

Or, take it one step further and simplify your li elements (while less repetitive, it does abstract what's happening):

const listItems = ["a","b","c"];

class Example extends PureComponent {

  isActive = item => this.props.someProp === item ? "myCssClass" : null  

  render = () => (
    <ul>
      {listItems.map(item => (
        <li key={item} className={isActive(item)}>
          { item.toUpperCase() }
        </li> 
      ))}
    </ul>
  )
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, that's the solution I was looking for
0

You can create function which will return classname

const classNames = (data)=>{
   swtich/case/if... what you want

   return 'SomeClassName'
}

<li className={this.classNames(dataFromStore)}>C</li>

2 Comments

But isn't it assumes that I should have different classes for every element?
yep, sorry a bit unclear your question. Unswer upper is good for you!

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.