Реагировать Js условно применяя атрибуты класса

202

Я хочу условно показать и скрыть эту группу кнопок в зависимости от того, что передается от родительского компонента, который выглядит так:

<TopicNav showBulkActions={this.__hasMultipleSelected} />

....

__hasMultipleSelected: function() {
  return false; //return true or false depending on data
}

....

var TopicNav = React.createClass({
render: function() {
return (
    <div className="row">
        <div className="col-lg-6">
            <div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">
                <button type="button" className="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
                  Bulk Actions <span className="caret"></span>
                </button>
                <ul className="dropdown-menu" role="menu">
                  <li><a href="#">Merge into New Session</a></li>
                  <li><a href="#">Add to Existing Session</a></li>
                  <li className="divider"></li>
                  <li><a href="#">Delete</a></li>
                </ul>
            </div>
        </div>
    </div>
    );
  }
});

Однако ничего не происходит с помощью {this.props.showBulkActions? 'показать скрытое'}. Я здесь что-то не так?

  • 0
    Вы также можете рассмотреть реакцию-бутстрап , так как это абстрагирует некоторые вещи класса в свойства компонентов, делая то, что вы пытаетесь сделать, немного проще.
Теги:
twitter-bootstrap-3

12 ответов

371
Лучший ответ

фигурные скобки внутри строки, поэтому она оценивается как строка. Они должны быть снаружи, поэтому это должно работать:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? 'show' : 'hidden')}>

Обратите внимание на пробел после "pull-right". Вы не хотите случайно предоставлять класс "pull-rightshow" вместо "pull-right show". Также должны быть круглые скобки.

  • 1
    Спасибо! Мне пришлось немного изменить его, потому что по какой-то причине он вообще не выводил pull-right btn-group. Просто показать или спрятать.
  • 0
    Это особенно полезно в некоторых случаях, когда classnames могут не подходить. Если вы находитесь в своей функции render и у вас есть map , вы можете знать только, хотите ли вы добавить класс во время рендеринга, поэтому этот ответ весьма полезен для этого.
Показать ещё 4 комментария
58

Как отмечали другие, classnames утилита - это рекомендуемый в настоящее время подход для обработки условных имен классов CSS в ReactJs.

В вашем случае решение будет выглядеть так:

var btnGroupClasses = classNames(
  'btn-group',
  'pull-right',
  {
    'show': this.props.showBulkActions,
    'hidden': !this.props.showBulkActions
  }
);

...

<div className={btnGroupClasses}>...</div>

В качестве побочного примечания я предлагаю вам попытаться избежать использования классов show и hidden, поэтому код может быть проще. Скорее всего, вам не нужно устанавливать класс для показа чего-либо по умолчанию.

  • 5
    Не могли бы вы уточнить, что утилита classNames является «рекомендуемым в настоящее время подходом»? Это отражено в каком-то уважаемом документе о передовом опыте? Или просто сарафанное радио вокруг React и classNames на данный момент?
  • 3
    @anied На момент написания статьи это было рекомендовано в официальной документации React: web.archive.org/web/20160602124910/http://facebook.github.io:80/…
Показать ещё 1 комментарий
46

Если вы используете транспилер (например, Babel или Traceur), вы можете использовать новый ES6 " строки шаблона".

Вот ответ @spitfire109, измененный соответственно:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'shown' : 'hidden'}`}>

Этот подход позволяет делать такие аккуратные вещи, предоставляя либо s-is-shown, либо s-is-hidden:

<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>
  • 10
    Будьте осторожны со вторым подходом, особенно в больших кодовых базах, так как он делает строки классов менее понятными. Например, если кто-то ищет s-is-shown или s-is-hidden в кодовой базе, он не найдет этот код.
6

Вы можете использовать здесь строковые литералы

 const Angle = ({show}) => {

 const angle = 'fa ${show ? 'fa-angle-down' : 'fa-angle-right'}';

 return <i className={angle} />
}
6

Или используйте npm classnames. Это очень легко и полезно, особенно для построения списка классов

6

Расходуя на @spitfire109 прекрасный ответ, можно сделать что-то вроде этого:

rootClassNames() {
  let names = ['my-default-class'];
  if (this.props.disabled) names.push('text-muted', 'other-class');

  return names.join(' ');
}

а затем внутри функции рендеринга:

<div className={this.rootClassNames()}></div>

хранит jsx short

3

Вы можете использовать массивы ES6 вместо классов. Ответ основан на статье доктора Акселя Раушмайера: Условно добавление записей внутри массивов и объектных литералов.

<div className={[
                 "classAlwaysPresent", 
                 ...Array.from(condition && ["classIfTrue"])
                ].join(" ")} />
  • 0
    пожалуйста, подробно об этом, в каком состоянии?
  • 0
    константное состояние = (1 === 1);
1

Более элегантное решение, которое лучше для обслуживания и удобочитаемости:

const classNames = ['js-btn-connect'];

if (isSelected) { classNames.push('is-selected'); }

<Element className={classNames.join(' ')}/>
0

2019:

Реакция на озеро много полезных. Но для этого вам не нужен пакет npm. просто создайте где-нибудь имя classnames функции и вызывайте его, когда вам нужно;

function classnames(obj){
  return Object.entries(obj).filter( p => p[1] ).map( p=>p[0] ).join(' ');
}

пример

  stateClass= {
    foo:true,
    bar:false,
    pony:2
  }
  classnames(stateClass) // return 'foo pony'
''
0

Это будет работать для вас

var TopicNav = React.createClass({
render: function() {

let _myClasses = 'btn-group pull-right {this.props.showBulkActions?'show':'hidden'}';

return (
            ...
            <div className={_myClasses}>
               ...
            </div>
    );
  }
});
0

Вы можете использовать этот пакет npm. Он обрабатывает все и имеет параметры для статических и динамических классов, основанных на переменной или функции.

// Support for string arguments
getClassNames('class1', 'class2');

// support for Object
getClassNames({class1: true, class2 : false});

// support for all type of data
getClassNames('class1', 'class2', null, undefined, 3, ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

<div className={getClassNames('show', {class1: true, class2 : false})} /> // "show class1"
-6

Вы можете использовать, если концепция такая

var Count=React.createClass({
getInitialState: function()
{
var state={counter:1};

setInterval(function(){
this.setState(
{counter:this.state.counter+(this.state.counter==1000?9999999999:1)})
}.bind(this),1);
return state;
},

render:function(){
return(
<div>
Counter<br/>
{this.state.counter}
</div>
)
}
}
)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню