如何组合多个内联样式对象?
Posted
技术标签:
【中文标题】如何组合多个内联样式对象?【英文标题】:How to combine multiple inline style objects? 【发布时间】:2015-07-10 20:09:20 【问题描述】:在 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);
如何组合多个对象并将它们分配在一起?
【问题讨论】:
【参考方案1】:如果你使用 React Native,你可以使用数组表示法:
<View style=[styles.base, styles.background] />
查看我的详细信息blog post。
【讨论】:
遗憾的是,您不能在常规 React 中执行此操作。 如果您使用的是 React-Native,这应该是公认的答案 您可以通过添加样式名称/值来稍微修改现有的内联样式。例如,<View style=this.state.error == false ? styles.base : [styles.base, backgroundColor: 'red'] />
对于两种静态样式,在渲染函数之外执行StyleSheet.compose()
可能更有效。它将生成一个新的静态样式表,该样式表只会通过网桥发送一次。 (此建议不适用于在运行时更改的样式,或者内联而不是样式表中的样式。)【参考方案2】:
您可以使用扩展运算符:
<button style=...styles.panel.button,...styles.panel.backButton>Back</button
【讨论】:
我收到“语法错误:意外标记”,指向第一个展开运算符中的第一个点。 @Izkata 你是在 react 还是 react native 中这样做,你能发布你的 sn-p React,类似于<div style= ...LEGEND_STYLE.box_base, ... 'background': '#123456' />
无论如何我都将其更改为使用像 <div style=LEGEND_STYLE.box_gen('#123456')
这样的辅助函数,所以对我来说没什么大不了的
即使对象只有一个键值对也可以使用,即使扩展运算符只对可迭代对象有效!你能解释一下为什么吗? developer.mozilla.org/en-US/docs/Web/javascript/Reference/…【参考方案3】:
您可以使用Object.assign()
来做到这一点。
在你的例子中,你会这样做:
ReactDOM.render(
<div style=Object.assign(divStyle, divStyle2)>
Hello World!
</div>,
mountNode
);
这将合并两种样式。如果有匹配的属性,第二个样式将替换第一个样式。
正如 Brandon 所说,如果您想在不应用 fontSize 的情况下重用 divStyle
,则应该使用 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>
【讨论】:
此解决方案可能会滥用Object.assign()
,从而导致一些不良后果。请参阅the answer here 一个更可靠的解决方案。
您的回答展示了一种滥用 Object.assign() 的方法。这对某些人来说可能是有用的信息,但不适用于我的示例。这个例子没有将默认值存储在对象中,对其进行变异,然后在其他地方重用变异的对象。
不同意。您在答案中解决了使用Object.assign()
的两种不同方式。第一个,在前几句话中,是我发现的滥用的一个例子(即,如果 OP 做了你在第一个 code
块中的建议,他/她会变异 divStyle
)。第二种方式 - 即,将它包装在一个函数中,就像你拥有的那样,将起作用,但答案并没有明确表明你正在 解决 Object.assign()
的常见“问题” wrt 不变性(虽然我个人认为为每个默认组件编写自定义无状态函数有点麻烦)。
哦,好的。确实如此。如果他想在不应用 fontSize 的情况下重用 divStyle ,则首先需要空对象。我会更新答案。
Object.assign() 是迄今为止实现连接的最方便的方法:)【参考方案4】:
与 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 operator 来组合两种样式。您也可以将Object.assign() 用于相同目的。
如果您不需要将样式存储在 var 中,这也可以使用
<Segment style=...segmentStyle, ...height:'100%'>
Your content
</Segment>
【讨论】:
只是为了添加到您的最后一个 sn-p,...segmentStyle, height:'100%' 也可以。【参考方案5】:Object.assign()
是一个简单的解决方案,但是(当前)top answer 的使用——虽然对于制作无状态组件来说很好,但会导致 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's blue.
<div style=styles.box></div>
一旦Object.assign()
执行,'styles.box' 对象就会永久更改。
解决方案是将一个空对象传递给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 这样的库非常有帮助。
【讨论】:
您关于如何滥用 Object.assign 的示例并不是对(当前)最佳答案中如何使用 Object.assign 的有效表示。 谢谢,进行了编辑以反映(当前)哪个方面是滥用 那里有一段不错的代码。 Object.assign(, this.state.showStartOverBtn ? : this.hidden ,this.btnStyle) 条件句也很有效【参考方案6】:Array notaion 是 React Native 中组合样式的最佳方式。
这显示了如何组合 2 个 Style 对象,
<Text style=[styles.base, styles.background] >Test </Text>
这显示了如何组合 Style 对象和属性,
<Text style=[styles.base, color: 'red'] >Test </Text>
这适用于任何 React Native 应用程序。
【讨论】:
问题是针对React
,而不是React Native
React 也可以使用相同的
React 从一开始就不支持数组,现在它不再工作了。
react 还不支持这样的组合样式。
不明白为什么这个响应有这么多的赞成票。回应题外话,这里我们谈论的是反应,而不是反应原生。 Reactjs 不支持此响应中所说的内容【参考方案7】:
const style1 =
backgroundColor: "#2196F3",
const style2 =
color: "white",
const someComponent = () =>
return <div style= ...style1, ...style2 >This has 2 separate styles</div>
注意双花括号。传播运算符是您的朋友。
【讨论】:
绝对应该被接受为正确答案。救生员! 我同意@RobHern。这应该是公认的答案,它还允许添加其他内联样式,例如: style=...styles.title, color: backgroundDark ? "#fff" : "#000"【参考方案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
或其他无用的类型也不会破坏样式。
【讨论】:
【参考方案9】:您还可以像这样将类与内联样式结合起来:
<View style=[className, paddingTop: 25]>
<Text>Some Text</Text>
</View>
【讨论】:
不,你不能那样做。这里说的是Reactjs(注意react native),不明白为什么这么赞【参考方案10】:我发现这对我最有效。它按预期覆盖。
return <View style=...styles.local, ...styles.fromProps />
【讨论】:
【参考方案11】:需要合并对象中的属性。 例如,
const boxStyle =
width : "50px",
height : "50px"
;
const redBackground =
...boxStyle,
background: "red",
;
const blueBackground =
...boxStyle,
background: "blue",
<div style=redBackground></div>
<div style=blueBackground></div>
【讨论】:
这绝对是聪明的。【参考方案12】:对于那些在 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/
【讨论】:
【参考方案13】:所以基本上我看错了。据我所知,这不是一个特定于 React 的问题,更多的是一个关于如何将两个 JavaScript 对象组合在一起的 JavaScript 问题(不破坏类似命名的属性)。
在这个 *** 答案中,它解释了它。 How can I merge properties of two JavaScript objects dynamically?
在 jQuery 中,我可以使用 extend 方法。
【讨论】:
【参考方案14】:为了扩展@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
【讨论】:
【参考方案15】:为了更进一步,您可以创建一个类似classnames 的辅助函数:
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>
【讨论】:
【参考方案16】:内联样式的方式:
<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 从一开始就不支持数组,现在它不再工作了。 以上评论是正确的,这个答案只适用于 React Native。可以做类似的事情 -如果您想根据条件添加样式,我已经为此构建了一个模块 像这样:
multipleStyles(styles.icon, [styles.iconRed]: true )
https://www.npmjs.com/package/react-native-multiple-styles
【讨论】:
【参考方案18】:在 React 中有多种内联样式。
<div onClick=eleTemplate style='width': '50%', textAlign: 'center'/>
【讨论】:
这是通过什么方式提供多种样式的? 样式接受花括号内的对象,因此您可以将所有样式作为一个对象并将其分配给一个变量,如下所示。 const combineStyles = 'width': '50%', textAlign: 'center'以上是关于如何组合多个内联样式对象?的主要内容,如果未能解决你的问题,请参考以下文章