React - DOM style.backgroundImage=?

I’m building a React-based paper doll RPG character screen. Just for fun. More of a challenge than I expected, honestly. I have a list of quests, and when you click that the quest is “completed”, the paper doll gets new gear. That “gear” is simply an image that loads over the area (head, body, legs, etc).

I can’t seem to figure out how to pull the appropriate image from a local file using DOM styling. Here’s my onClick() handler:

handleClick = (event, props) => {
        // copy this.state.quests into array for .map()
        var quests = [...this.state.quests];

        // toggle checked state
        quests.map((quest) => {
            if ( quest.name === props.name) {
                // toggle the checked flag in this.state.quests
                quest.checked = !quest.checked;

                // just using 'pdHead' for testing purposes (paper doll Head)
                const upgrade = document.getElementById('pdHead');
                // toggle background image on quest click
                quest.checked ?

                    // HERE'S THE PROBLEM - which format do I use to link to the file?
                    upgrade.style.backgroundImage="url('../images/TestImage.png')"

                    : upgrade.style.backgroundImage='none';
            } 

            return quest;
        })
        // object destructuring to update this.state.quests
        this.setState({ quests });
    }

First, I am able to do this by using ES6 import statements to import the image file, like this:

import TestImage from '../images/TestImage.png';

and then just use a template string in the ternary operator:

quest.checked 
    ? upgrade.style.backgroundImage=`url(${ TestImage })`
    : upgrade.style.backgroundImage='none';

This works, but I don’t want to do it this way (unless I have no other choice) because I will ultimately have dozens of pictures and I don’t want to import them all if I don’t have to.

I’ve tried all sorts of variations, but the ES6 import is the only one that works. I get no errors to help me figure out why it isn’t working because backgroundImage just defaults to ‘none’. I’ve tried:

upgrade.style.backgroundImage='url("../images/TestImage.png")'
upgrade.style.backgroundImage='require("../images/TestImage.png")'
upgrade.style.backgroundimage='url(require("../images/TestImage.png")'

Is this just something you can’t do? I can change the color and set all sorts of other styles this way, and I can grab an image from the Internet with no issues. I just can’t seem to use a local image without the import statement.

Any ideas? My goal is to have filepaths stored in the state, so when you click on a quest it populates the URL with the correct path for the quest. I can think of other ways to do this, but I’m trying to do it without writing a ton of code over and over. That’s also why I don’t want to use the import statements if I can avoid them.

Put your images in /public/images. Then url(images/foo.jpg) will work. If you put them in /src/images then webpack compiles that, it doesn’t really exist in the compiled code in the same way, which is why there is the need to use import

Also, React has an API for dynamically setting component styles, you shouldn’t need to use DOM methods. If you set the image string in the state, eg -

 <div style={{backgroundImage: this.state.bgImage }} >
2 Likes

Ah, thanks. Ever my hero.

1 Like