Changing the CSS background in React when updates occur

Currently working on toggling the CSS background image within this React application. The images have been successfully imported and a variable called "image" is set to the imported image as the iteration increases/decreases with each click.

The issue I'm encountering is that the body background image does not update accordingly. My understanding was that the background image should refresh in the componentDidUpdate method, as the iterative buttons toggle setState which triggers a re-render.

import Background1 from "../images/bg/1.png";
import Background2 from "../images/bg/3.png";
import Background3 from "../images/bg/4.png";


class UserPreferences extends Component {
  constructor(props) {
    super(props);
    this.state = {
      backgroundNumber: 1
    };
  }

  buttonNumberCalcPlus = () => {
    this.setState({ backgroundNumber: ++this.state.backgroundNumber });
  };

  buttonNumberCalcMinus = () => {
    this.setState({ backgroundNumber: --this.state.backgroundNumber });
  };

  componentDidUpdate() {
    var currentBackground = "Background" + this.state.backgroundNumber;
    console.log(currentBackground);

    var image;

    if (this.state.backgroundNumber == 1) {
      image = Background1;
    } else if (this.state.backgroundNumber == 2) {
      image = Background2;
    } else {
      image = Background3;
    }

    var mainBg = {
      backgroundImage: "url( " + { image } + ")"
    };
    console.log(mainBg);
    document.body.style = { mainBg };
  }

  render() {
    return (
      <div>
        <MainMenuToolbar />
        <h2 className="texttimezonepref">Update background image.</h2>
        <button
          id="next"
          onClick={this.buttonNumberCalcPlus}
          className="addbutton"
        >
          NEXT
        </button>
        <button
          id="prev"
          onClick={this.buttonNumberCalcMinus}
          className="subtractbutton"
        >
          PREV
        </button>
      </div>
    );
  }
}

Questioning whether this approach to changing the background in componentDidUpdate is correct:

var mainBg = {
  backgroundImage: "url( " + { image } + ")"
};


document.body.style = { mainBg };

Answer №1

Using document.body.style in JSX is incorrect as it does not support the syntax

document.body.style = {{ backgroundImage: "url( " + { image } + ")"}}
.

The correct method would be to apply your style changes directly to the target, like this:

document.body.style.backgroundImage = url(image)

Answer №2

Instead of utilizing the style property to assign an object, it is recommended to use style.background. This adjustment is necessary because the style object is not a standard plain object but a CSSStyleDeclaration. For more information on this topic, you can refer to the documentation on MDN.

When it comes to accessing the document, while the current method may work, I suggest using react-helmet, which offers a more organized approach for updating the document.

Answer №3

Is it appropriate to modify the background in componentDidUpdate using this method?

Actually, no.

The entire document's structure isn't the only one that can utilize the full viewport, and adjusting the body of the document excessively is not advisable. Most often, your app resides within a <div id="#root">, so you should alter the style property of your root div rather than the body itself.

By manipulating document.body, you are essentially bypassing React by directly attempting to make changes to the DOM node. This should only be done through the use of refs.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the correct approach to hiding problems in Flow NPM packages to ensure that end-user applications do not encounter any errors?

When utilizing something like $FlowIssue, it cannot be ensured that it will be included in every .flowconfig file. Defining a library interface appears to only function within the specific project and not in other projects that import the package (even if ...

What is the best way to center an image and text vertically using bootstrap?

I'm currently working on a Bootstrap website and have reached a section where I want to display text on the left and an image on the right. While I've managed to achieve this layout, I'm struggling with vertically centering the image. Despit ...

I am encountering difficulty retrieving data using useSelector in React Redux

I am trying to save all input values in Redux using dispatch and then return all the saved data from Redux using useSelector. In my Redux setup, I have created an object with multiple nested objects. However, I am facing an issue in retrieving the data fro ...

React Native ScrollView ref issue resolved successfully

I'm trying to automatically scroll to the bottom of a flatlist, so here's what I have: const scrollViewRef = useRef(); //my scroll view <ScrollView ref={scrollViewRef} onContentSizeChange={() => { scrollViewRef.current.scr ...

Tips for transforming a scroll element into the viewport using Angular 2+

This is a sample Here is a component with a list of items: class HomeComponent { text = 'foo'; testObject = {fieldFirst:'foo'}; itemList = [ '1', '2', '3', & ...

What are the ideal scenarios for implementing React.Fragments?

Today I discovered React Fragments and their benefits. I learned that fragments are more efficient by reducing the number of tree nodes and improving cleanliness in the inspector. However, is there still a need to use div tags as containers in React compo ...

Issue with Redux-form's type prop not functioning as expected with checkbox and radio components

Hey there, I'm new to working with redux forms and I've been trying to figure out how to use input types other than "text". I've read through the documentation but for some reason, types like "checkbox" or "radio" are not showing up in the b ...

Is it possible to eliminate jagged edges in CSS 2D rasterization by applying anti-aliasing to subpixels?

It appears that the HTML/CSS engine automatically rounds values to the nearest whole px unit. It would be interesting to see non-discrete sizing options (floats). A closer look reveals that in Chrome, widths/heights are rounded to the nearest physical pix ...

Deploying NextJs application with Firebase's static site generation (SS

TL;DR The new data I add to my project is not displaying on the site, even though it's in the database. The issue arises after deploying with Firebase. I created a meetup website using Firebase as the backend. Everything works fine in development mo ...

Storing User IP Address in Database with Express and Mongoose

I'm looking for a way to store users' IP addresses in mongoDB by using a mongoose model file for the user. Does anyone have any suggestions on how I can achieve this? Here is an example of the schema for the Users module file: const userSchema ...

Managing code requiring document.title in Next.js with Static Site Generation (SSG)

Currently, I have 2 dynamic SSG pages located under /blog/[slug]. Within these pages, I am rendering a component using next/link. When I click on these links to navigate to another slug, I encounter an issue. The problem arises when I want to execute some ...

Utilizing React-bodymovin's functionality to access methods for seamlessly looping animation sequences

Utilizing the react-bodymovin package has allowed me to embed a Bodymovin animation, but I'm interested in looping a specific section of the animation after it finishes playing once. When working with the HTML version of Bodymovin, achieving this loo ...

Tips for utilizing ion view within an ionic 2 application

In my original use of Ionic 1, I placed the footer after the <ion-content> and before . However, in the new Ionic 2, I can't seem to find any reference to <ion-view>. My specific need is to have two buttons at the bottom of the screen fol ...

Is it possible to generate an image from HTML using PHP?

Can anyone suggest a way to generate an image from pure HTML using PHP, possibly utilizing the GD library or other similar tools? I am looking to display icons from external sites and considering if creating an image would help improve load times. If not ...

Utilizing props to enhance styles in makeStyles

Is there a way in material-ui with makeStyles to spread props in an object and apply all the styles? For example: const useStyles = makeStyles(theme) => ({ card: { ...props # <- props includes properties like backgroundColor, fontSize, etc ...

Search for the precise date using a moment object in React

I am working on a React component that requires adding hours to a specified date based on the local time. render() { let offset = new Date().getTimezoneOffset(); let localDate1=(moment(processItem.beginTime).add(-offset/60,'h')); return( < ...

Tips on customizing the appearance of React rendering components

<div> <h3>{this.props.product.name}</h3> <h3>{this.props.product.code}</h3> {this.renderColors()} <article> <div da ...

The error message "Text content does not align with server-rendered HTML" occurring during React hydration in Next.js

When trying to implement dynamic SEO with a server-side API call, I encountered a Hydration error using Next.js. The issue was Text content does not match server-rendered HTML. I am determined to find a solution for dynamic SEO with a server-side API call ...

Adjust the position of the element by lifting it slightly

I am looking to adjust the positioning of the number "01 / 04" to match the layout shown in this image: Here is what I have accomplished so far: This is how the code structure looks like in vue js at the moment: <img id="theZoomImage" sizes="100vw" : ...

JavaScript problem with hovering action causing additional buttons to appear

Currently, I am developing a user interface where, upon hovering over an LI element, 2 buttons appear to provide additional functionality - "edit" and "remove". However, I am facing challenges with the mouse hit zones. The mouseover function works effect ...