Search code examples
reactjscreate-react-app

React JSX expression for className is not evaluated at runtime


I have the following template with the expression for the className property that I expect to be evaluated every time React calls the render method:

<ul className='ratings' onClick={this.handleClick}>
    <li className={'fa-star ' + (this.rating > 0) ? 'fas' : 'far'}></li>
</ul>

I expect it to be converted to this and this actually what online Babel transpiler shows:

React.createElement(
    'ul',
    { className: 'ratings', onClick: this.handleClick },

    React.createElement('li', { 
        'data-value': '1', 
        className: 'fa-star ' + (this.rating > 0) ? 'fas' : 'far' 
    })
);

I'm using create-react-app starter. And when I debug it I see the following:

createElement('li', { 
    'data-value': '1', className:  true ? 'fas' : 'far', 
    ...
})

It's like the expression is being evaluated during build time. What am I missing?


Solution

  • The problem is operator precedence. 'fa-star ' + (this.rating > 0) is evaluated as ternary condition and is always true.

    It should be:

    <li className={'fa-star ' + (this.rating > 0 ? 'fas' : 'far')}></li>
    

    A convenient helper for class joining is classnames:

    <li className={classnames('fa-star', { fas: !!this.rating, far: !this.rating })}></li>