여러 인라인 스타일 객체를 결합하는 방법은 무엇입니까?


214

React에서 객체를 명확하게 생성하고 인라인 스타일로 할당 할 수 있습니다. 즉. 아래에 언급.

var divStyle = {
  color: 'white',
  backgroundImage: 'url(' + imgUrl + ')',
  WebkitTransition: 'all', // note the capital 'W' here
  msTransition: 'all' // 'ms' is the only lowercase vendor prefix
};

var divStyle2 = {fontSize: '18px'};

React.render(<div style={divStyle}>Hello World!</div>, mountNode);

여러 객체를 결합하여 함께 할당하려면 어떻게해야합니까?


두 물체는 어떻게 생겼습니까?
Ryan

답변:


399

React Native를 사용하는 경우 배열 표기법을 사용할 수 있습니다.

<View style={[styles.base, styles.background]} />

이것에 대한 자세한 블로그 게시물을 확인하십시오.


41
안타깝게도 정기적 인 React에서는이 작업을 수행 할 수 없습니다.
YoTengoUnLCD

8
React-Native를 사용하는 경우 이것이 정답입니다.
calcazar

스타일 이름 / 값을 추가하여 기존 인라인 스타일을 약간 수정할 수 있습니다. 예를 들어,<View style={this.state.error == false ? styles.base : [styles.base, {backgroundColor: 'red'}]} />
Gürol Canbek

두 가지 정적 스타일의 StyleSheet.compose()경우 렌더링 기능 외부에서 수행하는 것이 더 효율적일 수 있습니다. 브릿지를 통해 한 번만 전송되는 새로운 정적 스타일 시트를 생성합니다. (이 조언은 런타임에 변경되거나 StyleSheet 대신 인라인 인 스타일에는 적용되지 않습니다.)
joeytwiddle

282

스프레드 연산자를 사용할 수 있습니다.

 <button style={{...styles.panel.button,...styles.panel.backButton}}>Back</button

8
첫 번째 스프레드 연산자의 첫 번째 점을 가리키는 "구문 오류 : 예기치 않은 토큰"이 표시됩니다.
이즈 카타

@Izkata 당신은 반응 또는 네이티브 반응으로 이것을하고 있습니까, 당신은 당신의 발췌 문장을 게시 할 수 있습니까
Nath

반응, 그것은 비슷했다<div style={{ ...LEGEND_STYLE.box_base, ...{ 'background': '#123456' } }} />
Izkata

어쨌든 같은 도우미 기능을 사용하도록 어쨌든 변경 <div style={LEGEND_STYLE.box_gen('#123456')}되었으므로 큰 문제는 아닙니다.
Izkata

스프레드 연산자가 반복 가능에만 유효하더라도 오브젝트에 키-값 쌍이 하나만있는 경우에도 작동합니다! 이유를 설명 할 수 있습니까? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Tyler

47

당신은 이것을 할 수 있습니다 Object.assign().

귀하의 예에서, 당신은 할 것입니다 :

ReactDOM.render(
    <div style={Object.assign(divStyle, divStyle2)}>
        Hello World!
    </div>,
    mountNode
);

두 가지 스타일이 병합됩니다. 일치하는 속성이있는 경우 두 번째 스타일이 첫 번째 스타일을 대체합니다.

Brandon이 언급했듯이 fontSize를 적용하지 않고 Object.assign({}, divStyle, divStyle2)재사용 하려면 사용해야 divStyle합니다.

이것을 사용하여 기본 속성을 가진 구성 요소를 만들고 싶습니다. 예를 들어 다음은 기본값을 가진 작은 상태 비 저장 구성 요소입니다 margin-right.

const DivWithDefaults = ({ style, children, ...otherProps }) =>
    <div style={Object.assign({ marginRight: "1.5em" }, style)} {...otherProps}>
        {children}
    </div>;

따라서 다음과 같이 렌더링 할 수 있습니다.

<DivWithDefaults>
    Some text.
</DivWithDefaults>
<DivWithDefaults className="someClass" style={{ width: "50%" }}>
    Some more text.
</DivWithDefaults>
<DivWithDefaults id="someID" style={{ marginRight: "10px", height: "20px"}}>
    Even more text.
</DivWithDefaults>

결과는 다음과 같습니다.

<div style="margin-right:1.5em;">Some text.</div>
<div style="margin-right:1.5em;width50%;" class="someClass">Some more text.</div>
<div style="margin-right:10px;height:20px;" id="someID">Even more text.</div>

5
이 솔루션은 Object.assign()바람직하지 않은 결과를 초래하는 방식으로 오용 될 가능성이 있습니다 . 보다 안정적인 솔루션에 대한 답변은 여기를 참조하십시오 .
Brandon

1
귀하의 답변은 Object.assign ()을 오용하는 방법을 보여줍니다. 그것은 일부 사람들에게 유용한 정보 일 수 있지만, 나의 예에는 적용되지 않습니다. 이 예제는 객체에 기본값을 저장하지 않고 변경 한 후 변형 된 객체를 다른 곳에서 재사용하는 것입니다.
qel

동의하지 않는다. 당신 Object.assign()은 당신의 대답에 두 가지 별도의 사용 방법을 설명 합니다. 첫 번째 문장의 첫 번째 문장은 내가 식별 한 오용의 예입니다 (즉, OP가 첫 번째 code블록 에서 조언 한 내용을 수행 한 경우 변경했습니다 {divStyle}). 두 번째 방법-예를 들어 함수에 래핑하면 효과가 있지만 대답은 '일반적인'gotcha 'wrt 불변성 문제를 해결 하고 있음을 명확하게 나타내지 않습니다 Object.assign()(개인적으로는 조금 생각합니다) 모든 기본 구성 요소에 대해 사용자 정의 상태 비 저장 함수를 작성하는 것은 번거 롭습니다).
Brandon

오 그래. 사실입니다. fontSize를 적용하지 않고 divStyle을 재사용하려면 먼저 빈 객체가 필요합니다. 답변을 업데이트하겠습니다.
qel

Object.assign ()은 연결을 달성하는 가장 편리한 방법입니다 :)
aldobsom

29

React Native와 달리 React에서 스타일 배열을 전달할 수 없습니다.

<View style={[style1, style2]} />

React에서는 style 속성에 전달하기 전에 단일 스타일 객체를 만들어야합니다. 처럼:

const Header = (props) => {
  let baseStyle = {
    color: 'red',
  }

  let enhancedStyle = {
    fontSize: '38px'
  }

  return(
    <h1 style={{...baseStyle, ...enhancedStyle}}>{props.title}</h1>
  );
}

ES6 Spread 연산자 를 사용하여 두 가지 스타일을 결합했습니다. 같은 목적으로 Object.assign () 을 사용할 수도 있습니다 .

var에 스타일을 저장할 필요가없는 경우에도 작동합니다

<Segment style={{...segmentStyle, ...{height:'100%'}}}>
    Your content
</Segment>

배열을 스타일로 전달할 수 없습니까?
heisenberg

3
마지막 스 니펫에 추가하기 만하면 {{... segmentStyle, height : '100 %'}}도 작동합니다.
Luke Brandon Farrell 19 년

26

Object.assign()쉬운 솔루션이지만 (현재) 최고 답변 의 사용법은 상태 비 저장 구성 요소를 만드는 데는 좋지만 두 state개체 를 병합하는 OP의 원하는 목표에 문제를 일으킬 것입니다 .

두 개의 인수를 사용 Object.assign()하면 실제로 첫 번째 객체를 제자리에서 변경하여 향후 인스턴스화에 영향을줍니다.

전의:

상자에 대해 가능한 두 가지 스타일 구성을 고려하십시오.

var styles =  {
  box: {backgroundColor: 'yellow', height: '100px', width: '200px'},
  boxA: {backgroundColor: 'blue'},
};

따라서 모든 상자에 기본 'box'스타일을 갖기를 원하지만 다른 색상으로 덮어 쓰려고합니다.

// this will be yellow
<div style={styles.box}></div>

// this will be blue
<div style={Object.assign(styles.box, styles.boxA)}></div>

// this SHOULD be yellow, but it's blue.
<div style={styles.box}></div>

일단 Object.assign()실행 되면 'styles.box'객체가 변경됩니다.

해결책은에 빈 객체를 전달하는 것 Object.assign()입니다. 그렇게함으로써, 전달한 객체로 새로운 객체를 생성하는 방법을 알려줍니다. 이렇게 :

// this will be yellow
<div style={styles.box}></div>

// this will be blue
<div style={Object.assign({}, styles.box, styles.boxA)}></div>

// a beautiful yellow
<div style={styles.box}></div>

제자리에서 변경되는 객체에 대한 이러한 개념은 React에 중요하며, 올바른 사용은 Object.assign()Redux와 같은 라이브러리를 사용하는 데 실제로 도움이됩니다.


1
Object.assign을 오용하는 방법에 대한 예는 Object.assign이 (현재) 최상위 답변에서 사용되는 방법을 올바르게 나타내는 것은 아닙니다.
qel

감사합니다, 어떤 측면이 (현재) 오용인지 반영하도록 수정되었습니다
Brandon

1
좋은 코드 조각이 있습니다. Object.assign ({}, this.state.showStartOverBtn? {} : this.hidden, this.btnStyle)} 조건부도 매력처럼 작동합니다
steveinatorx

17

Array Notaion은 반응 네이티브에서 스타일을 결합하는 가장 좋은 방법입니다.

2 개의 Style 객체를 결합하는 방법을 보여줍니다.

<Text style={[styles.base, styles.background]} >Test </Text>

스타일 객체와 속성을 결합하는 방법을 보여줍니다.

<Text style={[styles.base, {color: 'red'}]} >Test </Text>

이것은 모든 반응 네이티브 응용 프로그램에서 작동합니다.


2
질문은입니다 React하지React Native
디미타르 Tsonev

React에도 동일하게 사용할 수 있습니다
Sasindu Lakshitha

React는 처음부터 배열을 지원하지 않으며 더 이상 작동하지 않습니다.
witoong623

반응은 아직 이와 같은 결합 스타일을 지원하지 않습니다.
화난 키위

12

다음과 같이 클래스를 인라인 스타일과 결합 할 수도 있습니다.

<View style={[className, {paddingTop: 25}]}>
  <Text>Some Text</Text>
</View>

8

실제로 결합하는 공식적인 방법이 있으며 다음과 같습니다.

<View style={[style01, style02]} />

그러나 작은 문제 가 있습니다. 그중 하나가 부모 구성 요소에 의해 전달되고 결합 된 공식적인 방법으로 만들어진 경우 큰 문제가 있습니다.

// The passing style02 from props: [parentStyle01, parentStyle02]

// Now:
<View style={[style01, [parentStyle01, parentStyle02]]} />

그리고이 마지막 줄은 UI 버그를 유발합니다 .React Native는 배열 내부의 깊은 배열을 처리 할 수 ​​없습니다. 그래서 도우미 기능을 만듭니다.

import { StyleSheet } from 'react-native';

const styleJoiner = (...arg) => StyleSheet.flatten(arg);

내 사용하여 styleJoiner어디서나 당신은 스타일의 모든 유형을 결합과 스타일을 결합 할 수 있습니다. 짝수 undefined또는 다른 쓸모없는 유형은 스타일을 손상시키지 않습니다.


5

나는 이것이 나에게 가장 효과적이라는 것을 발견했다. 예상대로 재정의됩니다.

return <View style={{...styles.local, ...styles.fromProps}} />

2

React 에서이 솔루션을 찾는 사람들의 경우 스프레드 연산자를 스타일 내부에서 사용하려면 babel-plugin-transform-object-rest-spread를 사용해야합니다.

npm 모듈로 설치하고 .babelrc를 다음과 같이 구성하십시오.

{
  "presets": ["env", "react"],
  "plugins": ["transform-object-rest-spread"]
}

그런 다음처럼 사용할 수 있습니다 ...

const sizing = { width: 200, height: 200 }
 <div
   className="dragon-avatar-image-background"
   style={{ backgroundColor: blue, ...sizing }}
  />

추가 정보 : https://babeljs.io/docs/en/babel-plugin-transform-object-rest-spread/


2

이것을 더 발전시키기 위해 클래스 이름 과 같은 도우미 함수를 만들 수 있습니다 .

const styleRules = (...rules) => {
  return rules.filter(Boolean).reduce((result, rule) => {
    return { ...result, ...rule };
  }, {});
};

그런 다음 구성 요소에서 조건부로 사용하십시오.

<div style={

  styleRules(
    divStyle,
    (window.innerWidth >= 768) && divStyleMd,
    (window.innerWidth < 768) && divStyleSm
  )

}>Hello World!</div>

0

그래서 기본적으로 나는 이것을 잘못된 방식으로보고 있습니다. 내가 본 것으로부터, 이것은 React 특정 질문이 아니며, 두 개의 JavaScript 객체를 함께 결합하는 방법에 대한 JavaScript 질문입니다 (유사하게 명명 된 속성을 방해하지 않고).

이 StackOverflow 답변에서 설명합니다. 두 JavaScript 객체의 속성을 동적으로 병합하려면 어떻게해야합니까?

jQuery에서 extend 메소드를 사용할 수 있습니다.


1
CSS 스타일이 포함 된 객체로 작업 할 때는 객체를 병합하는 것만으로는 충분하지 않습니다. 병합 기능에 의해 올바른 순서로 처리되어야하는 속기 속성, 다른 문자 케이싱 등이 있습니다. 나는 그러한 기능을 제공하는 라이브러리를 찾고 있지만 아직 찾지 못했습니다.
sompylasar

속기 속성 확장을 수행하는 라이브러리는 다음과 같습니다. github.com/kapetan/css-shorthand-expand 이지만 완벽한 솔루션은 아닙니다.
sompylasar

0

@PythonIsGreat가 말한 것을 확장하기 위해 나를 위해 사용할 전역 함수를 만듭니다.

var css = function(){
    var args = $.merge([true, {}], Array.prototype.splice.call(arguments, 0));
    return $.extend.apply(null, args);
}

이를 통해 객체를 새 객체로 깊게 확장하고 다양한 개수의 객체를 매개 변수로 사용할 수 있습니다. 이를 통해 다음과 같은 작업을 수행 할 수 있습니다.

return(
<div style={css(styles.base, styles.first, styles.second,...)} ></div>
);

var styles = {
  base:{
    //whatever
  },
  first:{
    //whatever
  },
  second:{
    //whatever
  }
}

CSS 스타일이 포함 된 객체로 작업 할 때는 일반 객체 병합 기능으로는 충분하지 않습니다. 위의 답변에 대한 내 의견을 참조하십시오.
sompylasar


0

인라인 스타일링 방법 :

<View style={[styles.red, {fontSize: 25}]}>
  <Text>Hello World</Text>
</View>

<View style={[styles.red, styles.blue]}>
  <Text>Hello World</Text>
</View>

  <View style={{fontSize:10,marginTop:10}}>
  <Text>Hello World</Text>
</View>

3
React는 처음부터 배열을 지원하지 않으며 더 이상 작동하지 않습니다.
witoong623
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.