React에서 조건부 스타일을 처리하는 올바른 방법


93

지금 React를하고 있는데 조건부 스타일링을위한 "올바른"방법이 있는지 궁금합니다. 튜토리얼에서 그들은

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

인라인 스타일링을 사용하지 않는 것을 선호하므로 대신 클래스를 사용하여 조건부 스타일을 제어하고 싶습니다. React 사고 방식으로 어떻게 접근할까요? 아니면이 인라인 스타일링 방식을 사용해야합니까?


1
난 당신이있을 수 있습니다 생각 reduxreact혼동. Redux는 스타일링과 관련이 없습니다.
rossipedia

3
문서에 대한 선호도는 확실하지만 마크 업 교환 호환성이 중요하지 않은 응용 프로그램에는 지나치게 열성적이라고 생각합니다. 일부 주요 웹 앱은 실제로 클래스를 제거하고 인라인 스타일 만 사용합니다. 이는 5 가지 적용된 규칙 중 텍스트를 굵게 만드는 것보다 더 예측 가능하고 추론하기 쉽습니다. 속성이 동적 일 때는 반복적 인 문서 에서처럼 대역폭을 많이 절약하지 않습니다. 응용 프로그램의 의미 (보기 소스 마크 업) 중요한 하나 ... 것이 아니다
dandavis

@rossipedia 아 예 감사합니다, 혼란스러워서 이것에 대해 생각할 때 redux 튜토리얼을보고있었습니다. 감사합니다!
davidhtien

계단식으로 인해 텍스트 장식의 가치가 무엇인지 확실하지 않고 complete가 true 인 경우에만 라인 스루를 적용하려는 경우 스타일 개체를 작성해야합니다. 이렇게하면 다른 값일 때 실수로 없음으로 설정하지 않습니다. CONST 스타일 = {} 경우 (완전한) {스타일 [ 'textDecoration'] = "라인을 통해 '}
에드워드

답변:


78

클래스 이름을 사용하려면 반드시 클래스 이름을 사용하십시오.

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

classnames 패키지가 도움 이 될 수도 있습니다. 이를 통해 코드는 다음과 같습니다.

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

조건부 스타일을 수행하는 "올바른"방법은 없습니다. 당신에게 가장 잘 맞는 것을하십시오. 나는 인라인 스타일링을 피하고 방금 설명한 방식으로 클래스를 사용하는 것을 선호합니다.

POSTSCRIPT [2019 년 8 월 6 일]

React가 스타일링에 대해 의견이없는 것은 사실이지만 요즘에는 CSS-in-JS 솔루션을 권장합니다. 즉, 스타일 구성 요소 또는 감정 . React를 처음 사용하는 경우 처음부터 CSS 클래스 또는 인라인 스타일을 고수하십시오. 그러나 React에 익숙해지면 이러한 라이브러리 중 하나를 채택하는 것이 좋습니다. 모든 프로젝트에서 사용합니다.


조건부 스타일링 방법으로 className을 사용하기로 결정했다면 안녕하세요. 포함하지 않는 classNames lib. undefined대신 을 사용하는 것이 좋습니다 null. className⚡️ - | 유형 (정의되지 않은 문자열) - 속성은 문자열이나 정의되지 않은 입력 입력으로 소요
0xx 같은

3
@JadRizk 더 나은 방법은 설정할 유효한 값이없는 경우 className을 전혀 설정하지 않는 것입니다. const attrs = completed?{className:'text-strike'}:{}그런 다음 <li {...attrs}>text to maybe strike</li>(확산 연산자). 이렇게하면 할당 할 좋은 값이 없으면 className을 전혀 설정하지 않습니다. 이것은 현재 값이 무엇인지 알 수없는 일부 인라인 스타일을 설정하는 데 중요한 접근 방식입니다 (제어 할 수없는 파일의 CSS에 의해 설정 될 수 있기 때문입니다).
LinuxDisciple

@LinuxDisciple 모든 필드가 거짓으로 평가 classnames되면 빈 문자열 만 반환합니다. 이것은 CSS의 영향을받지 않습니다.
David L. Walsh

내가 JadRizk의 솔루션 사이의 잘못된 선택이라고 생각 시간 전 DavidL.Walsh @ nullundefined그 여전히없는 값을 초래할 것이다 classhtml로의 속성 (예 : <p class></p>대신 <p></p>내가 설정을 피할 수있는 방법을 제공하므로) className전혀합니다. 그것이 발생함에 따라 JadRizk의 솔루션에 대해 잘못되었습니다. 명시된 문제에 대해 JadRizk의 개선을 통한 솔루션이 가장 좋습니다. 내 구문은 임의의 소품 목록과 해당 값을 조건부로 설정할 수 있지만 클래스 이름을 설정하는 것은 과잉입니다.
LinuxDisciple 19-09-06

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

위의 코드를 확인하십시오. 그것은 트릭을 할 것입니다.


3
정확히 이와 같은 것을 찾고있었습니다. 조건부 인라인 스타일링 감사합니다.
Souvik Ghosh

<div style = {{가시성 : this.state.driverDetails.firstName! == 정의되지 않았습니까? 'visible': 'hidden'}}> </ div>. ==에 작은 오타가 있습니다.
vinayak shahdeo

31

인라인 스타일을 조건부로 적용해야하는 경우 (모두 적용하거나 전혀 적용하지 않음) 다음 표기법도 작동합니다.

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

'someCondition'이 충족되지 않은 경우 빈 개체를 전달합니다.


2
이 패턴은 불필요한 diff를 생성하지 않습니까? DOM은 diffing의 나의 이해는 것입니다 style여기에 소품 항상 자바 스크립트부터 바꿀 것 {} != {} 나는 diffing의에 대한 올바른 해요 경우 "아마도 그것은 사용하는 것이 좋습니다, undefined"대신 " {}"
도슨 B

1
좋은 메모. 이것에 대해 잘 모르겠습니다.
Vlado

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이면 false를 반환하므로 이것이 스타일에 어떤 영향을 미치는지 고려해야 할 수도 있습니다.

다른 솔루션이 더 모범 사례 일 수 있지만 공유 할 가치가 있다고 생각했습니다.


3

또 다른 방법은 인라인 스타일과 스프레드 연산자를 사용하는 것입니다.

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

이 방법은 조건에 따라 여러 속성을 동시에 추가하려는 일부 상황에서 유용합니다.


1
기본 스타일을 변경하지 않으려면 좋은 접근 방식
dhilt

2

나는 같은 질문에 대답하는 동안이 질문을 발견했다. 클래스 배열 및 조인에 대한 McCrohan의 접근 방식은 견고합니다.

제 경험을 통해 저는 React로 변환되는 많은 레거시 루비 코드로 작업 해 왔으며 구성 요소를 구축하면서 기존 CSS 클래스와 인라인 스타일 모두에 도달했습니다.

구성 요소 내부의 예제 스 니펫 :

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

다시 말하지만, 레거시 CSS 코드에 손을 뻗어 컴포넌트와 함께 "패키징"하고 계속 진행합니다.

그래서 나는 그 레이블이 당신의 프로젝트에 따라 크게 다를 것이기 때문에 무엇이 "최고"인지에 관해서는 공기 중에 약간 있다고 느낍니다.


당신의 엉망의 비트 것으로, 스타일의 속성과 클래스 이름을 결합해서는 안
세바스찬 Voráč에게

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>;
  }

또는 classnames NPM 패키지를 사용하여 동적 및 조건부 className props를 더 간단하게 사용할 수 있습니다 (특히 조건부 문자열 조작보다 더).

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'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.