如何组合多个内联样式对象?

在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);

如何组合多个对象并将它们分配在一起?

310484 次浏览

所以基本上我看问题的方式是错误的。从我所看到的,这不是一个React特定的问题,更多的是一个JavaScript问题,在我如何结合两个JavaScript对象在一起(没有打击类似命名的属性)。

在这个StackOverflow的答案中,它解释了这一点。如何动态合并两个JavaScript对象的属性?

在jQuery中,我可以使用extend方法。

为了扩展@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
}
}

你可以用Object.assign()来实现。

在你的例子中,你会这样做:

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

这样两种风格就合并了。如果有匹配的属性,则第二个样式将取代第一个样式。

正如Brandon所指出的,如果你想重用divStyle而不应用fontSize,你应该使用Object.assign({}, divStyle, divStyle2)

我喜欢使用它来创建具有默认属性的组件。例如,这里有一个默认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>

你可以使用展开运算符:

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

Object.assign()是一个简单的解决方案,但是(目前)上面的回答对它的使用-虽然用于制作无状态组件还不错,但会导致OP合并两个state对象的理想目标出现问题。

有了两个参数,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. xmlBox的对象被永久更改。

解决方案是将一个空对象传递给Object.assign()。这样做是在告诉该方法用传递给它的对象生成一个NEW对象。像这样:

// 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,你可以使用数组符号:

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

查看我关于这个的详细博客

我已经为此构建了一个模块,如果你想根据条件添加样式 这样的:< / p >
multipleStyles(styles.icon, { [styles.iconRed]: true })

https://www.npmjs.com/package/react-native-multiple-styles

与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 传播算子来组合两种风格。你也可以使用Object.assign ()来达到同样的目的。

如果你不需要将你的样式存储在一个变量中,这也可以工作

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

你也可以像这样将类与内联样式结合起来:

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

对于那些在React中寻找这个解决方案的人,如果你想在风格中使用扩散操作符,你应该使用:babel-plugin-transform-object-rest-spread。

通过npm模块安装它,并配置你的.babelrc:

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

然后你可以用like…

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/

为了更进一步,你可以创建一个类似__abc0的helper函数:

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>

内联样式化的方法:

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

数组表示法是react native中组合样式的最佳方式。

这展示了如何组合2个Style对象,

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

这展示了如何组合样式对象和属性,

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

这将适用于任何react本机应用程序。

其实有一种正式的组合方式,如下所示:

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

但是,有一个小问题,如果其中一个被父组件传递,并且它是通过组合形式的方式创建的,我们就有一个大问题:

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


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

最后一行导致UI bug, React Native不能处理数组中的深数组。所以我创建了我的helper函数:

import { StyleSheet } from 'react-native';


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

通过在任何地方使用我的styleJoiner,你可以组合任何类型的风格和组合风格。即使undefined或其他无用的类型也不会破坏样式。

我发现这个方法最适合我。它会像预期的那样重写。

return <View style=\{\{...styles.local, ...styles.fromProps}} />
    const style1 = {
backgroundColor: "#2196F3",
}
    

const style2 = {
color: "white",
}


const someComponent = () => {
return <div style=\{\{ ...style1, ...style2 }}>This has 2 separate styles</div>
}
    

注意双花括号。播音接线员是你的朋友。

需要合并对象中的属性。 例如,< / p >

const boxStyle = {
width : "50px",
height : "50px"
};
const redBackground = {
...boxStyle,
background: "red",
};
const blueBackground = {
...boxStyle,
background: "blue",
}








<div style={redBackground}></div>
<div style={blueBackground}></div>

在React中有多个内联样式。

<div onClick={eleTemplate} style=\{\{'width': '50%', textAlign: 'center'}}/>

你可以使用组成

 const styles = StyleSheet.create({
divStyle :{
color: 'white',
backgroundImage: 'url(' + imgUrl + ')',
WebkitTransition: 'all', // note the capital 'W' here
msTransition: 'all' // 'ms' is the only lowercase vendor prefix
},
divStyle2 :{fontSize: '18px'}
})
        

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

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

要在react js中添加多个内联样式,你可以这样做

<div style=\{\{...styles.cardBody,...{flex:2}}}>