Oliver Watkins
Oliver Watkins

Reputation: 13539

Inlining dynamic css style in JSX

I have a hundred images which I want to add as a background to 100 div elements in my page.

I have a common style (style), and then I have the variable part which is the image. I use Object.assign to create style1, style2, style3 etc, which merges the static with the variable part.

It looks something like this :

let style = {width:w, height:h, backgroundColor:'red', border :'5px solid red'}

let style1 = Object.assign(style, {backgroundImage:"url(" + img1 + ")"});
let style2 = Object.assign(style, {backgroundImage:"url(" + img2 + ")"});
....
let style100 = Object.assign(style, {backgroundImage:"url(" + img100 + ")"});


return (
  <div>
      <div style={style1}>1</div>
      <div style={style2}>2</div>
      <div style={style3}>3</div>

    ...

      <div style={style99}>99</div>
      <div style={style100}>100</div>
  </div>
);

This looks very ugly...

Is there an 'inline' way of doing this? Something like so :

<div style={Object.assign(style, {backgroundImage:"url(" + img1 + ")")}>1</div>
<div style={Object.assign(style, {backgroundImage:"url(" + img2 + ")")}>2</div>

Upvotes: 1

Views: 4148

Answers (2)

bennygenel
bennygenel

Reputation: 24680

A small addition to @OriDrori's answer that you can also pass array of objects to style prop.

<div style={[style, { backgroundImage: `url(${img1})` }]}>1</div>

So this also means you can create a small function that can return an object with the correct background image

const getBackgroundImage = (image) => {
  return { backgroundImage: `url(${image})` };
}

<div style={[style, getBackgroundImage(img1)]}>1</div>

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 192477

You can use proposal-object-rest-spread (you'll need babel's Object rest spread transform) to merge the background image with the style object. In addition you can use a template literal to inject the img dynamic part into the static part:

<div style={{ ...style, backgroundImage: `url(${img1})` }}>1</div>

btw - all of this should be done in a loop, probably using Array#map, and you might want to create a component for each image.

You'll have an array of images ['img1', 'img2', 'img3', etc...].

An image component would be something like this:

const Image = ({ style, img, text }) => (
    <div style={{ ...style, backgroundImage: `url(${img}.png)` }}>{text}</div>
);

And the outer component's render would probably look like this:

render() {
    const {images} = this.props;

    return (
        images.map((img, index) => (
            <Image style={style} img={img} text={index} key={img} />
        ))
    );
}

Upvotes: 6

Related Questions