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


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.