347

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?

0

22 Answers 22

611

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Sadly you can't do this in regular React.
This should be the accepted answer if you're using React-Native
You can slightly modify existing inline style by adding the style names/values. For example, <View style={this.state.error == false ? styles.base : [styles.base, {backgroundColor: 'red'}]} />
For two static styles, doing StyleSheet.compose() outside the render function might be more efficient. It will produce a new static stylesheet that will only be sent over the bridge once. (This advice does not apply to styles which change at runtime, or which are inline instead of in a StyleSheet.)
357

You can use the spread operator:

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

8 Comments

I get "Syntax error: Unexpected token", pointing at the first dot in the first spread operator.
@Izkata Are you doing this in react or react native, could you post your snippet
React, it was something like <div style={{ ...LEGEND_STYLE.box_base, ...{ 'background': '#123456' } }} />
I changed it anyway to use a helper function like <div style={LEGEND_STYLE.box_gen('#123456')} anyway, so it's not a big deal to me
This even works if the object has only one key-value pair, even though spread operators are only supposed to be valid for iterables! Can you explain why? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
|
74

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>

5 Comments

this solution is potentially misusing Object.assign() in a way that would lead to some undesirable consequences. See the answer here a more reliable solution.
Your answer demonstrates a way to misuse Object.assign(). That might be useful information for some people, but it doesn't apply to my example. This example is not storing the default in an object, mutating it, then reusing the mutated object somewhere else.
disagree. you address two separate ways of using Object.assign() in your answer. the first, in the first few sentences, is an example of the misuse I identified (ie, if OP did what you advise in your first code block, he/she'd mutate {divStyle}). the second way--ie, wrapping it in a function as you have, will work, but the answer doesn't make it clear that you're working around Object.assign()'s common 'gotcha' wrt immutability (though personally I think it's a little cumbersome to write a custom stateless function for every default component).
Oh, OK. That's true. If he wanted to reuse divStyle without applying the fontSize it'd need the empty object first. I'll update the answer.
Object.assign() is by far the most convenient way to achieve a concatenation :)
56

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>

2 Comments

Just to add to your last snippet, {{...segmentStyle, height:'100%'}} will also work.
This is actually the correct answer because the question was about styling of React, not React-native. Thanks pal.
33

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.

3 Comments

Your example of how to misuse Object.assign is not a valid representation of how Object.assign is being used in the (currently) top answer.
thanks, made edits to reflect which aspect is (currently) a misuse
nice piece of code right there. Object.assign({}, this.state.showStartOverBtn ? {} : this.hidden ,this.btnStyle)} conditionals also work like a charm
28

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.

5 Comments

The questions is for React, not React Native
You can use same for React also
React doesn't support array from the beginning and now it doesn't work anymore.
react not yet support combine style like this.
Do not understand why this rensponse have such upvote. Response off topic, here we talk about react, not react-native. Reactjs do not support what is say in this response
27
    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.

2 Comments

Should absolutely be accepted as the correct answer. Life saver!
I agree with @RobHern. This should be the accepted answer, which also allows adding other inline styles, like: style={{...styles.title, color: backgroundDark ? "#fff" : "#000"}}
22

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.

Comments

13

You can also combine classes with inline styling like this:

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

1 Comment

No, you cant do that. What is say here is Reactjs (note react native), not understand why have it such upvote
8

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>

1 Comment

this was absolutely clever.
7

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

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

Comments

5

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

2 Comments

This was the solution that worked for me. The accepted solution did not work. On Expo 44 + ReactNative 0.64.3.
Stylesheet compose didn't work for me on react native. Passing styles as array worked brilliantly.
3

To add multiple styles inline in react js, you can do like this

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

1 Comment

using spread is operator is right approach , if you are in ES6. This is the right Answer. Also a good example for combining styles classes and in-line style method
2

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/

Comments

1

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. How can I merge properties of two JavaScript objects dynamically?

In jQuery I can use the extend method.

Comments

1

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

Comments

1

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>

Comments

1

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>

2 Comments

React doesn't support array from the beginning and now it doesn't work anymore.
the above comment is correct, this answer only works in React Native. it is possible to do something similar - <View style={{...styles.red, ...styles.blue}} /> like so, which React does support.
1

Can write like this:

<div style={{ background: "white", color: "green" }}>

Comments

0

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

Comments

0

Below is an example that shows how it plays well with Typescript with React Native. Same rules apply for react in terms of styling.



type ButtonT = {
  title: string;
  bgColor?: string; // optional prop
  borderRadius: number; // mandatory prop
};

const Button = ({ title, bgColor, borderRadius }: ButtonT) => {
  return (
    <Pressable
      style={{
        ...styles.buttonContainer,

        /* conditionally rendering as this is an optional prop */
        ...(bgColor && { backgroundColor: bgColor }),

        /* this can also be written just as borderRadius with es6 syntax */
        borderRadius: borderRadius,
      }}
    >
      <Text>{title}</Text>
    </Pressable>
  );
};

export default Button;

Comments

-5

To have multiple Inline styles in React.

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

2 Comments

In which way is this provide a multiple style?
The style accepts an object within curly braces, so you can have all your styles as a single object and assign it to one variable as below. const combinedStyles = {'width': '50%', textAlign: 'center'} <div onClick={eleTemplate} style={combinedStyles}/>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.