1

Okay , so iv been stuck on this for a few hours now and have tried everything i could think of / read up on. In my project i have 3 buttons, each button should change the background image of my site. the background image is tied to the default "App" div element in a react project. I am trying to write javascript code that changes the image based on what color is clicked ( the background image is a scooter, only the scooter color is what is intended to change, its not just a blank color covering the background)

Here is my javascript file to change the colors

document.getElementById("green").addEventListener(onclick, changeColorGreen);
document.getElementById("black").addEventListener(onclick, changeColorBlack);
document.getElementById("silver").addEventListener(onclick, changeColorSilver);

let greenurl = "url('../images/GreenScooter')"
let blackurl = "url('../images/GreenScooter')"
let silverurl = "url('../images/GreenScooter')"

export function changeColorGreen() {
  document.getElementById("App").style.backgroundImage = greenurl;
}
export function changeColorSilver() {
  document.getElementById("App").style.backgroundImage = silverurl;
}
export function changeColorBlack() {
  document.getElementById("App").style.backgroundImage = blackurl;
}

and this is my JSX component, well the part that pertains to this anyway:

import { changeColorBlack, changeColorGreen, changeColorSilver } from "./colorSelector";

          <div className="d-flex mx-auto pt-5" id="colorselector">
            <button type="button" class="btn btn-success mx-2" onClick={changeColorGreen} id="green"></button>
            <button type="button" class="btn btn-success mx-2" onClick={changeColorBlack} id="black"></button>
            <button type="button" class="btn btn-success mx-2" onClick={changeColorSilver} id="silver"></button>
          </div>
        </div>

i have tried all the different ways suggested via various stackOverFlow threads, youtube and google. Most of them suggested putting the URL in a variable but it still doesnt work. I tested the code and changed it so that it changes the entire background to the 3 different colors and not images and it works just fine. However trying to get it to change to the different images just wont work. Any help or guidance on the matter would be greatly appreciated thank you

2
  • 1
    You're mixing React-like code with non-react like code. Usually react wants to completely own the DOM, and you shouldn't manually make changes to it. I'd expect a JSX component to exists for your 'App' with a style attribute that's changed there. Background image should probably be in a state variable. Commented Jan 31, 2023 at 18:25
  • react uses virtual DOM and then it reconciles with the actual DOM so manipulating the actual DOM with code document.getElementById("App").style.backgroundImage can cause unexpected bugs. Commented Jan 31, 2023 at 19:28

1 Answer 1

1

As @Evert commented, ReactJs things work much better if you use the "ReactJS Way of Thinking".

ReactJS is all about state. If something changes in any way and this change makes the appearance/behavior of your application change, this must be expressed as a state.

In you specific case, changing the background of a div element according to the buttons clicked, the background is your state.

Let's consider, for simplicity, we just need to change the background color.

import { useState } from "react";

function App() {

  const [color, setColor] = useState('yellow');

  return (
    <div>
      <div style={{backgroundColor: `${color}`}}>
        {color}
      </div>
      <div>
        <button onClick={() => setColor('green')}>Green</button>
        <button onClick={() => setColor('red')}>Red</button>
        <button onClick={() => setColor('yellow')}>Yellow</button>
      </div>
    </div>
  );
}

export default App;

This code would work fine. It expresses the color as a state with

const [color, setColor] = useState('yellow');

Now see this button

<button onClick={() => setColor('green')}>Green</button> 

When you click it, the onClick event triggers and change the state, setting the color to 'green'. When the state changes, the component is rerendered and the background-color is set to green.

Now let's see how to do the same with a background-image. My prefered way is using classes.

App.css

.image-green {
  background-image: url("./img-green.png");
}

.image-red {
  background-image: url("./img-red.png");
}

.image-yellow {
  background-image: url("./img-yellow.png");
}

App.js

import { useState } from "react";

import "./App.css";

function App() {

  const [color, setColor] = useState('green');

  return (
    <div>
      <div class={`image-${color}`} style={{ width: "100px", height: "100px"}}></div>
      <div>
        <button onClick={() => setColor('green')}>Green</button>
        <button onClick={() => setColor('red')}>Red</button>
        <button onClick={() => setColor('yellow')}>Yellow</button>
      </div>
    </div>
  );
}

export default App;

Here again, when a button is clicked, the state changes and the component is re-rendered, with the correct background image.

Just don't forget two point:

  • In the setState(), put your desired initial state. In my case I opted for starting with the green image.

  • Put the images used in the appropriate directory. In my case I used these three images in the src/ directory, but you may opt for other solutions.

Image with a green 1 Image with a red 2 Image with a yellow 3

I also gave some width and height to the div, to make images appear.

If you want to test, just create a ReactJS app using create-react-app, replace the contents of App.js and App.css with the contents above and run it.

Hope it helps!

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

4 Comments

thank you for the detailed reply. About an hour after my original post i done something very similar. however, now when i do it this way my background changes to just white. iv done it your way and another way which does pretty much the exact same just with a importing the images instead of setting the url in the css file. both give me white backgrounds
i'll start the project from scratch and implement this first as a test. i must have some bad code somewhere thats stopping it from working. There are no errors in the console and upon inspecting element it does change the image, it just doesnt appear on the browser for some reason and changes to white
@ChrisDk Based on your question, I created a video for my Youtube channel answering it. There you may see how it happens. youtube.com/watch?v=T2Fp9uTmabc
Unfortunately it is in Portuguese, @ChrisDk, but the automatic subtitles provided by Youtube may help to get the big picture.

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.