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

时间:2015-04-30 23:13:31

标签: reactjs

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

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

18 个答案:

答案 0 :(得分:300)

如果您正在使用React Native,则可以使用数组表示法:

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

有关详细信息,请参阅docs

答案 1 :(得分:247)

您可以使用点差运算符:

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

答案 2 :(得分:38)

您可以使用Object.assign()执行此操作。

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

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

这将合并两种风格。如果有匹配的属性,第二种样式将替换第一种样式。

正如Brandon所说,如果你想重复Object.assign({}, divStyle, divStyle2)而没有应用fontSize,你应该使用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>

答案 3 :(得分:19)

Object.assign()是一个简单的解决方案,但(目前)top answer使用它 - 虽然适合制作无状态组件,但会导致OP的问题合并两个state对象的理想目标。

有两个参数,Object.assign()实际上会改变第一个就地对象,影响未来的实例化。

例如:

考虑一个盒子的两种可能的样式配置:

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

所以我们希望我们所有的盒子都有默认的盒子&#39;样式,但想要用不同的颜色覆盖一些:

// 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()后,&#39; styles.box&#39;对象改变了。

解决方案是将空对象传递给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这样的库非常有帮助。

答案 4 :(得分:19)

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

答案 5 :(得分:15)

实际上,有一种正式的合并方式,如下所示:

<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或其他无用的类型也不会破坏样式。

答案 6 :(得分:10)

您还可以将类与内联样式组合在一起,如下所示:

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

答案 7 :(得分:7)

我发现这最适合我。它会按预期覆盖。

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

答案 8 :(得分:4)

    const style1 = {
        backgroundColor: "#2196F3", 
    }
    
    const style2 = {
        color: "white", 
    }

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

请注意双大括号。传播者是您的朋友。

答案 9 :(得分:3)

数组概念是在react native中组合样式的最佳方法。

这显示了如何组合两个Style对象,

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

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

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

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

答案 10 :(得分:1)

对于那些在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/

答案 11 :(得分:1)

要使这一步更进一步,您可以创建类似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>

答案 12 :(得分: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
  }
}

答案 13 :(得分:0)

需要合并对象中的属性。 例如,

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




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

答案 14 :(得分: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>

答案 15 :(得分:0)

如果您想根据条件添加样式,我已为此构建了一个模块 像这样:

multipleStyles(styles.icon, { [styles.iconRed]: true })

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

答案 16 :(得分:0)

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

在这个StackOverflow答案中,它解释了它。 How can I merge properties of two JavaScript objects dynamically?

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

答案 17 :(得分:-2)

在 React 中拥有多个内联样式。

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