В React вы можете четко создать объект и назначить его как встроенный стиль. i.e.., упомянутых ниже.
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);
Как объединить несколько объектов и назначить их вместе?
Если вы используете React Native, вы можете использовать нотацию массива:
<View style={[styles.base, styles.background]} />
Подробнее см. docs.
Вы можете использовать оператор спреда:
<button style={{...styles.panel.button,...styles.panel.backButton}}>Back</button
Вы можете сделать это с помощью Object.assign()
.
В вашем примере вы бы сделали:
ReactDOM.render(
<div style={Object.assign(divStyle, divStyle2)}>
Hello World!
</div>,
mountNode
);
Это объединит два стиля. Второй стиль заменит первый, если есть соответствующие свойства.
Как отметил Брэндон, вы должны использовать Object.assign({}, divStyle, divStyle2)
, если вы хотите повторно использовать divStyle
без применения fontSize к нему.
Мне нравится использовать это для создания компонентов со свойствами по умолчанию. Например, здесь небольшой компонент без состояния с по умолчанию 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>
Object.assign()
таким образом, что это может привести к нежелательным последствиям. Смотрите ответ здесь, более надежное решение.
Object.assign()
является простым решением, но ( в настоящее время) топ ответ использование его - в то время как раз отлично для изготовления компонентов без гражданства, вызовет проблемы для OP желаемой цели слияния двух state
объектов.
С двумя аргументами Object.assign()
фактически мутирует первый объект на месте, влияя на будущие экземпляры.
Пример:
Рассмотрим две возможные конфигурации стилей для коробки:
var styles = {
box: {backgroundColor: 'yellow', height: '100px', width: '200px'},
boxA: {backgroundColor: 'blue'},
};
Поэтому мы хотим, чтобы все наши блоки имели стили "по умолчанию", но хотим перезаписать их другим цветом:
// 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 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.
В отличие от React Native, мы не можем передать массив стилей в React, например
<View style={[style1, style2]} />
В React нам нужно создать отдельный объект стилей перед передачей его в свойство стиля. Подобно:
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>
Вы также можете комбинировать классы со встроенным стилем так:
<View style={[className, {paddingTop: 25}]}>
<Text>Some Text</Text>
</View>
Способы встроенного моделирования:
<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>
Чтобы пойти еще дальше, вы можете создать вспомогательную функцию classnames -like:
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>
Для тех, кто ищет это решение в 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/
Я построил для этого модуль, если вы хотите добавить стили на основе условия например:
multipleStyles(styles.icon, { [styles.iconRed]: true })
Чтобы развернуть то, что сказал @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
}
}
Так что в основном я смотрю на это не так. Из того, что я вижу, это не конкретный вопрос React, а скорее вопрос JavaScript в том, как объединить два объекта JavaScript вместе (без сбивания аналогично названных свойств).
В этом ответе StackOverflow это объясняется. Как я могу объединить свойства двух объектов JavaScript динамически?
В jQuery я могу использовать метод extend.