React: Dynamically setting background

Created on 22 Apr 2016  路  4Comments  路  Source: facebook/react

Consider this code:

var css = {background: 'url('+backgroundURL+') no-repeat center center', backgroundSize: backgroundSize, backgroundColor: backgroundColor};

<div className='background' style={css} />

the css rendered is:

background:url(www.com) no-repeat center center; background-size:contain; background-color:rgb(176, 55, 61);

Which is expected. But when you change backgroundURL, it also removes background-size and background-color. The result becomes:

background: url("www.com") 50% 50% no-repeat;

Most helpful comment

This is a result of the fact that you are combining the short syntax and then setting extra specific properties. This is fine for initial render, however since only background is updated on render, when that is set on the node, it overrides the other properties. Just like with plain CSS the order of operations is important to remember. My recommendation is to not treat JS styles like CSS because it is dynamic (unlike CSS). Either use the shortcut syntax entirely or ensure that each property you want set is explicitly declared.

Here's it in action https://jsfiddle.net/9x2jby1z/ (your issue) vs https://jsfiddle.net/9x2jby1z/1/ (working due to explicit setting of only backgroundImage).

Since we don't intend to write a CSS parser and know the varying ways that you can specify these shorthand properties, I think I'm going to close this out as an unfortunate but expected behavior. Sorry it caused you problems!

All 4 comments

This is a result of the fact that you are combining the short syntax and then setting extra specific properties. This is fine for initial render, however since only background is updated on render, when that is set on the node, it overrides the other properties. Just like with plain CSS the order of operations is important to remember. My recommendation is to not treat JS styles like CSS because it is dynamic (unlike CSS). Either use the shortcut syntax entirely or ensure that each property you want set is explicitly declared.

Here's it in action https://jsfiddle.net/9x2jby1z/ (your issue) vs https://jsfiddle.net/9x2jby1z/1/ (working due to explicit setting of only backgroundImage).

Since we don't intend to write a CSS parser and know the varying ways that you can specify these shorthand properties, I think I'm going to close this out as an unfortunate but expected behavior. Sorry it caused you problems!

@zpao Could you let me know if this is related? This has been driving me bonkers:

let avatar = Path.join(remote.app.getPath('appData'), '/Doomtrooper/assets/cardart/bannermen.png');
console.log(avatar); // prints C:\Users\justin\AppData\Roaming\Doomtrooper\assets\cardart\bannermen.png
<div
    style={{
        ...style.avatar,
        background: `url("${avatar}") no-repeat center`
    }}
/>

But it's broken and renders:
image

Note: This behavior ONLY happens on windows.

Originally I thought it was an Electron bug (https://github.com/electron/electron/issues/12102) but now I'm starting to think it's something with the react parser on Windows?

Any help is greatly appreciated!

(note the workaround is to componentWillReceiveProps() and then load the image in anImage() tag and when it loads setState({img: src}) (which SHOULD be the same URL) but doing a setState in cdu will make @gaearon angry... :(

React doesn't have a parser. We're literally passing a string you gave to the browser. I encourage you to create a reproduction case without React (i.e. just DOM API) and ask in Electron support forums).

Thanks @gaearon. I'll continue down that path!

Was this page helpful?
0 / 5 - 0 ratings