How to combine multiple inline style objects?

Reactjs

Reactjs Problem Overview


In React you can clearly create an object and assign it as an inline style. i.e.. mentioned below.

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

How can I combine multiple objects and assign them together?

Reactjs Solutions


Solution 1 - Reactjs

If you're using React Native, you can use the array notation:

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

Check out my detailed blog post about this.

Solution 2 - Reactjs

You can use the spread operator:

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

Solution 3 - Reactjs

You can do this with Object.assign().

In your example, you would do:

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

That will merge the two styles. The second style will replace the first if there are matching properties.

As Brandon noted, you should use Object.assign({}, divStyle, divStyle2) if you want to reuse divStyle without the fontSize applied to it.

I like to use this to make components with default properties. For example, here's a little stateless component with a default margin-right:

const DivWithDefaults = ({ style, children, ...otherProps }) =>
    <div style={Object.assign({ marginRight: "1.5em" }, style)} {...otherProps}>
        {children}
    </div>;

So we can render something like this:

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

Which will give us the result:

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

Solution 4 - Reactjs

Unlike React Native, we cannot pass array of styles in React, like

<View style={[style1, style2]} />

In React, we need to create the single object of styles before passing it to style property. Like:

const Header = (props) => {
  let baseStyle = {
    color: 'red',
  }

  let enhancedStyle = {
    fontSize: '38px'
  }

  return(
    <h1 style={{...baseStyle, ...enhancedStyle}}>{props.title}</h1>
  );
}

We have used ES6 Spread operator to combine two styles. You can also use Object.assign() as well for the same purpose.

This also works if you don't need to store your style in a var

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

Solution 5 - Reactjs

Object.assign() is an easy solution, but the (currently) top answer's usage of it — while just fine for making stateless components, will cause problems for the OP's desired objective of merging two state objects.

With two arguments, Object.assign() will actually mutate the first object in-place, affecting future instantiations.

Ex:

Consider two possible style configs for a box:

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

So we want all our boxes to have default 'box' styles, but want to overwrite some with a different color:

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

Once Object.assign() executes, the 'styles.box' object is changed for good.

The solution is to pass an empty object to Object.assign(). In so doing, you're telling the method to produce a NEW object with the objects you pass it. Like so:

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

This notion of objects mutating in-place is critical for React, and proper use of Object.assign() is really helpful for using libraries like Redux.

Solution 6 - Reactjs

Array notaion is the best way of combining styles in react native.

This shows how to combine 2 Style objects,

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

this shows how to combine Style object and property,

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

This will work on any react native application.

Solution 7 - Reactjs

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

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

Note the double curly brackets. The spread operator is your friend.

Solution 8 - Reactjs

Actually, there is a formal way to combine and it is like below:

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

But, there is a small issue, if one of them is passed by the parent component and it was created by a combined formal way we have a big problem:

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

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

And this last line causes to have UI bug, surly, React Native cannot deal with a deep array inside an array. So I create my helper function:

import { StyleSheet } from 'react-native';

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

By using my styleJoiner anywhere you can combine any type of style and combine styles. even undefined or other useless types don't cause to break the styling.

Solution 9 - Reactjs

You can also combine classes with inline styling like this:

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

Solution 10 - Reactjs

I've found that this works best for me. It overrides as expected.

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

Solution 11 - Reactjs

Need to merge the properties in object. For Example,

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




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

Solution 12 - Reactjs

For ones that looking this solution in React, If you want to use the spread operator inside style, you should use: babel-plugin-transform-object-rest-spread.

Install it by npm module and configure your .babelrc as such:

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

Then you can use like...

const sizing = { width: 200, height: 200 }
 <div
   className="dragon-avatar-image-background"
   style={{ backgroundColor: blue, ...sizing }}
  />

More info: https://babeljs.io/docs/en/babel-plugin-transform-object-rest-spread/

Solution 13 - Reactjs

You can use compose

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

OR

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

Solution 14 - Reactjs

So basically I'm looking at this in the wrong way. From what I see, this is not a React specific question, more of a JavaScript question in how do I combine two JavaScript objects together (without clobbering similarly named properties).

In this StackOverflow answer it explains it. https://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically

In jQuery I can use the extend method.

Solution 15 - Reactjs

To Expand on what @PythonIsGreat said, I create a global function that will do it for me:

var css = function(){
    var args = $.merge([true, {}], Array.prototype.splice.call(arguments, 0));
    return $.extend.apply(null, args);
}

This deeply extends the objects into a new object and allows for a variable number of objects as parameters. This allows you to do something like this:

return(
<div style={css(styles.base, styles.first, styles.second,...)} ></div>
);

var styles = {
  base:{
    //whatever
  },
  first:{
    //whatever
  },
  second:{
    //whatever
  }
}

Solution 16 - Reactjs

To take this one even further, you could create a classnames-like helper function:

const styleRules = (...rules) => {
  return rules.filter(Boolean).reduce((result, rule) => {
    return { ...result, ...rule };
  }, {});
};

And then use it conditionally in your components:

<div style={

  styleRules(
    divStyle,
    (window.innerWidth >= 768) && divStyleMd,
    (window.innerWidth < 768) && divStyleSm
  )

}>Hello World!</div>

Solution 17 - Reactjs

Ways of inline styling:

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

Solution 18 - Reactjs

I have built an module for this if you want to add styles based on a condition like this:

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

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

Solution 19 - Reactjs

To have multiple Inline styles in React.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPythonIsGreatView Question on Stackoverflow
Solution 1 - ReactjsNickView Answer on Stackoverflow
Solution 2 - ReactjsNathView Answer on Stackoverflow
Solution 3 - ReactjsqelView Answer on Stackoverflow
Solution 4 - Reactjsachyut pokhrelView Answer on Stackoverflow
Solution 5 - ReactjsBrandonView Answer on Stackoverflow
Solution 6 - ReactjsSasindu LakshithaView Answer on Stackoverflow
Solution 7 - ReactjsjasonleonhardView Answer on Stackoverflow
Solution 8 - ReactjsAmerllicAView Answer on Stackoverflow
Solution 9 - ReactjsGil PerezView Answer on Stackoverflow
Solution 10 - ReactjsAdrian BartholomewView Answer on Stackoverflow
Solution 11 - ReactjsNarayanan View Answer on Stackoverflow
Solution 12 - ReactjsPhoenixView Answer on Stackoverflow
Solution 13 - ReactjsAvinashView Answer on Stackoverflow
Solution 14 - ReactjsPythonIsGreatView Answer on Stackoverflow
Solution 15 - ReactjstimthezView Answer on Stackoverflow
Solution 16 - ReactjsstreletssView Answer on Stackoverflow
Solution 17 - ReactjshimView Answer on Stackoverflow
Solution 18 - ReactjsdubbelnisseView Answer on Stackoverflow
Solution 19 - ReactjsMANISH PARGANIHAView Answer on Stackoverflow