Правильный способ обработки условного стиля в React


93

Я сейчас немного занимаюсь React, и мне было интересно, есть ли «правильный» способ создания условных стилей. В учебнике они используют

style={{
  textDecoration: completed ? 'line-through' : 'none'
}}

Я предпочитаю не использовать встроенные стили, поэтому вместо этого хочу использовать класс для управления условным стилем. Как можно подойти к этому с точки зрения мышления React? Или я должен просто использовать этот способ встроенного стиля?


1
Думаю, вы могли reduxи reactзапутались. Redux не имеет ничего общего со стилем.
rossipedia 03

3
Я думаю, что вы безошибочно предпочитаете документы, но излишне усердны для приложений, в которых совместимость разметки не важна. некоторые основные веб-приложения фактически избавляются от классов и используют только встроенный стиль, который более предсказуем и легче рассуждать, чем какое из 5 применяемых правил делает текст жирным. когда атрибуты динамические, вы не экономите много трафика, как при работе с повторяющимися документами. семантика приложения (разметка исходного кода) тоже не так важна ...
dandavis

@rossipedia ах да, спасибо, перепутала, смотрела на руководство по сокращению, когда думала об этом, спасибо!
davidhtien

Если вы не уверены, какое значение будет иметь text-decoration из-за каскада, и вы хотите применить сквозную строку только в том случае, если значение complete истинно, вам нужно будет создать объект стиля. Таким образом, вы не установите значение none случайно, когда это было другое значение. const style = {} if (complete) {style ['textDecoration'] = 'line-through'}
Эдвард,

Ответы:


78

Если вы предпочитаете использовать имя класса, обязательно используйте имя класса.

className={completed ? 'text-strike' : null}

Вы также можете найти пакет classnames полезным. С ним ваш код будет выглядеть так:

className={classNames({ 'text-strike': completed })}

Не существует «правильного» способа создания условных стилей. Делайте то, что лучше всего подходит для вас. Лично я предпочитаю избегать встроенных стилей и использовать классы только что описанным способом.

Постскриптум [06-АВГ-2019]

Хотя остается верным, что React не разделяет мнения о стилях, в наши дни я бы порекомендовал решение CSS-in-JS; а именно стилизованные компоненты или эмоции . Если вы новичок в React, для начала придерживайтесь классов CSS или встроенных стилей. Но как только вы освоитесь с React, я рекомендую использовать одну из этих библиотек. Я использую их в каждом проекте.


Привет, если вы решили использовать className в качестве метода условного стиля. Без classNames lib. Советую использовать undefinedвместо null. classNameСвойство принимает в качестве входных данных введите строку или неопределенный - типа (String | неопределенную) - ⚡️
0XX

3
@JadRizk - еще лучший подход - вообще не устанавливать className, если у вас нет допустимого значения для его установки. const attrs = completed?{className:'text-strike'}:{}затем <li {...attrs}>text to maybe strike</li>(оператор распространения). Таким образом, вы вообще не устанавливаете className, если у вас нет подходящего значения для назначения. Это важный подход для установки некоторых встроенных стилей, когда вы не можете знать текущее значение (потому что оно может быть установлено CSS в файле, который вы не можете контролировать).
LinuxDisciple

@LinuxDisciple, если все поля оцениваются как ложные, classnamesпросто возвращает пустую строку. Никакой CSS не повлияет на это.
Дэвид Л. Уолш

@ DavidL.Walsh 21 час назад я подумал, что решение JadRizk было ложным выбором, nullи undefinedэто все равно приведет к classатрибуту без значения в html (т.е. <p class></p>вместо <p></p>), поэтому я предоставил метод, который classNameвообще избегает настройки . Так получилось, что я ошибался насчет решения JadRizk. Для заявленной проблемы я считаю, что ваше решение с уточнением JadRizk является лучшим. Мой синтаксис может устанавливать произвольный список свойств и их значений условно, но просто установить имя класса излишне.
LinuxDisciple

106
 <div style={{ visibility: this.state.driverDetails.firstName != undefined? 'visible': 'hidden'}}></div>

Ознакомьтесь с приведенным выше кодом. Это поможет.


3
Именно это и искал. Условный встроенный стиль, спасибо.
Souvik Ghosh

<div style = {{видимость: this.state.driverDetails.firstName! == undefined? 'visible': 'hidden'}}> </div>. Небольшая опечатка в ==.
vinayak shahdeo

31

Если вам нужно условно применить встроенные стили (применить все или ничего), то эта нотация также работает:

style={ someCondition ? { textAlign:'center', paddingTop: '50%'} : {}}

В случае, если someCondition не выполнено, вы передаете пустой объект.


2
Но разве этот шаблон не создает ненужных различий? Я понимаю различие DOM в том, что styleопора здесь всегда будет меняться, поскольку в Javascript. {} != {} Если я прав в отношении различий, возможно, лучше использовать " undefined" вместо " {}"
Доусон Б.

1
Хорошее примечание. Я не уверен в этом.
Владо

8

Во-первых, я согласен с вами в отношении стиля - я бы также (и делаю это) условно применил классы, а не встроенные стили. Но вы можете использовать ту же технику:

<div className={{completed ? "completed" : ""}}></div>

Для более сложных наборов состояний накопите массив классов и примените их:

var classes = [];

if (completed) classes.push("completed");
if (foo) classes.push("foo");
if (someComplicatedCondition) classes.push("bar");

return <div className={{classes.join(" ")}}></div>;

6

вместо этого:

style={{
  textDecoration: completed ? 'line-through' : 'none'
}}

вы можете попробовать следующее, используя короткое замыкание:

style={{
  textDecoration: completed && 'line-through'
}}

https://codeburst.io/javascript-short-circuit-conditionals-bbc13ac3e9eb

ключевой бит информации из ссылки:

Короткое замыкание означает, что в JavaScript, когда мы оцениваем выражение И (&&), если первый операнд ложен, JavaScript выполняет короткое замыкание и даже не смотрит на второй операнд.

Стоит отметить, что это вернет false, если первый операнд - false, поэтому, возможно, придется подумать, как это повлияет на ваш стиль.

Другие решения могут быть более передовыми, но подумал, что стоит поделиться.


3

Другой способ, используя встроенный стиль и оператор распространения

style={{
  ...completed ? { textDecoration: completed } : {}
}}

Этот способ может быть полезен в некоторых ситуациях, когда вы хотите добавить кучу свойств одновременно на основе условия.


1
Хороший подход, если вы не хотите менять стиль по умолчанию
dhilt

2

Я столкнулся с этим вопросом, пытаясь ответить на тот же вопрос. Подход МакКрохана к массиву классов и объединению является надежным.

Благодаря своему опыту я работал с большим количеством устаревшего кода Ruby, который конвертируется в React, и по мере создания компонента (ов) я обнаружил, что обращаюсь как к существующим классам css, так и к встроенным стилям.

пример фрагмента внутри компонента:

// if failed, progress bar is red, otherwise green 
<div
    className={`progress-bar ${failed ? failed' : ''}`}
    style={{ width: this.getPercentage() }} 
/>

Опять же, я обращаюсь к унаследованному коду css, «упаковываю» его с компонентом и двигаюсь дальше.

Так что я действительно чувствую, что вопрос о том, что является «лучшим», еще не ясен, поскольку этот лейбл будет сильно различаться в зависимости от вашего проекта.


Вы не должны комбинировать classNames с атрибутом стиля, это немного беспорядок
Себастьян Ворач

0

Лучший способ справиться со стилем - использовать классы с набором свойств css.

пример:

<Component className={this.getColor()} />

getColor() {
    let class = "badge m2";
    class += this.state.count===0 ? "warning" : danger;
    return class;
}

0

Вы можете использовать что-то вроде этого.

render () {
    var btnClass = 'btn';
    if (this.state.isPressed) btnClass += ' btn-pressed';
    else if (this.state.isHovered) btnClass += ' btn-over';
    return <button className={btnClass}>{this.props.label}</button>;
  }

Или же вы можете использовать пакет NPM classnames , чтобы упростить работу с динамическими и условными props className (особенно в большей степени, чем с условными манипуляциями со строками).

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.