Правильний спосіб обробки умовного стилю в React


95

Зараз я роблю якийсь React, і мені було цікаво, чи існує "правильний" спосіб зробити умовний стиль. У підручнику, який вони використовують

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

Я вважаю за краще не використовувати вбудований стиль, тому я хочу замість цього використовувати клас для управління умовним стилем. Як можна підходити до цього в способі мислення React? Або я повинен просто використовувати цей вбудований спосіб стилізації?


1
Я думаю, ви могли б reduxі reactзаплутати. Redux не має нічого спільного зі стилізацією.
россіпедія

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

@rossipedia ах так дякую, переплутався, дивився на підручник з redux, коли думав про це, дякую!
davidhtien

Якщо ви не впевнені, якою буде цінність текстового оформлення через каскад, і ви хочете застосувати прохідну лінію лише у випадку, якщо повна істина, вам доведеться створити об'єкт стилю. Таким чином, ви не встановите для нього випадково, коли це було інше значення. const style = {} if (complete) {style ['textDecoration'] = 'line-through'}
Едвард

Відповіді:


78

Якщо ви віддаєте перевагу використовувати назву класу, неодмінно використовуйте назву класу.

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

Вам також може виявитися корисним пакет імен класів . З ним ваш код буде виглядати так:

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атрибуту no-value у 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 = {{visibility: this.state.driverDetails.firstName! == undefined? 'visible': 'приховано'}}> </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, коли ми обчислюємо вираз AND (&&), якщо перший операнд хибний, JavaScript буде замикатися і навіть не дивитись на другий операнд.

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

Інші рішення могли б бути кращою практикою, але вважали, що варто поділитися ними.


3

Інший спосіб - використання вбудованого стилю та оператора розвороту

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

Цей спосіб буде корисним у деяких ситуаціях, коли ви хочете додати купу властивостей одночасно на основі умови.


1
Гарний підхід, якщо ви не хочете змінювати стиль за замовчуванням
dhilt

2

Я зіткнувся з цим запитанням, намагаючись відповісти на це саме питання. Підхід Маккрохана до класу array & join є твердим.

Завдяки своєму досвіду я працював із великою кількістю застарілого рубінового коду, який перетворюється на React, і, будуючи компоненти, я виявляю, що я прагну як до існуючих класів css, так і до вбудованих стилів.

фрагмент прикладу всередині компонента:

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

Знову ж таки, я виявляю, що звертаюся до застарілого коду css, «упаковуючи» його в компонент і рухаюся далі.

Отже, я справді відчуваю, що це трохи в повітрі щодо того, що є "найкращим", оскільки цей ярлик буде сильно відрізнятися залежно від вашого проекту.


Не слід поєднувати classNames з атрибутом style, це трохи
безладно

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, щоб зробити динамічні та умовні реквізити 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.