Alter the app's entire background color in React.js with a button click

I am facing an issue with changing the background color of my entire React App when a button is clicked. Currently, I am able to change the color of the button itself but not the background. I have imported the App.css file into my project and I am looking for a way to dynamically update the CSS of the App using a separate function called ChangeColor. This function is located in my Header.js which is then included in the App.js

Is there a solution to achieve this? Here is the code snippet:

import React, {useState} from "react";
import Button from "react-bootstrap/esm/Button";
import '../../../App.css'

function ChangeColor() {
    const [isActive, setIsActive] = useState(false);
    const handleClick = () => {
        setIsActive(current => !current);
    };

    return(
        <Button 
            style={{
                backgroundColor: isActive ? 'red' : '',
                color: isActive ? 'white' : '',
            }}
            onClick={handleClick}
        > Test </Button>
    )
}

export default ChangeColor
.App {
  text-align: center;
  background-color: white;
}

Answer №1

When considering ways to address this issue, a few solutions stand out.

  1. One option is to store the background color in the state and switch between colors based on the current state.

(A quick note - it's advisable not to name your component ChangeColor as it may not accurately reflect the component's purpose. Perhaps using ButtonChangeColor would be more appropriate.)

const { useState } = React;

function Example() {

  const [bgColor, setBgColor] = useState('white');

  function toggleBackground() {
    if (bgColor === 'white') setBgColor('black');
    if (bgColor === 'black') setBgColor('white');
  }

  const appStyle = ['App', bgColor].join(' ');

  return (
    <div className={appStyle}>
      <button onClick={toggleBackground}>
        Toggle background
      </button>
    </div>
  );

}

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
.App {
  height: 100vh;
  background-color: white;
}

.black { background-color: black; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

  1. Alternatively, you can utilize CSS variables and adjust the current stylesheet through the CSSStyleDeclaration interface without needing to maintain state. The toggleBackground function can remain outside the component, independent of state requirements.

function toggleBackground() {
  const { style } = document.documentElement;
  const bgColor = style.getPropertyValue('--bg-color');
  if (bgColor === 'white' || bgColor === '') {
    style.setProperty('--bg-color', 'black');
  } else {
    style.setProperty('--bg-color', 'white');
  }
}

function Example() {
  return (
    <div className="App">
      <button onClick={toggleBackground}>
        Toggle background
      </button>
    </div>
  );
}

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
:root { --bg-color: white; }

.App {
  height: 100vh;
  background-color: var(--bg-color);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Answer №2

To easily manage the state of isActive and color, consider utilizing localStorage for storage.

const [isActive, setIsActive] = useState(localStorage.getItem('is_active') || false);
    const handleClick = () => {
        setIsActive(current => !current);
    };


<Button 
      style={{
          backgroundColor: isActive ? 'red' : '',
          color: isActive ? localStorage.getItem('bg_color') : '',
      }}
      onClick={handleClick}
  > Test </Button>

Answer №3

Your code is experiencing an issue because you are manipulating the properties of the button instead of acting on the element whose color you intend to change.

Within this code snippet, the button is altering the color of the root div. It's important to note that this demonstration serves solely to highlight the problem at hand. There exist numerous approaches to achieving the desired outcome, some aligning with best practices more than others. The purpose of this response is simply to address why the current approach is ineffective, rather than prescribing the optimal method. For a comprehensive explanation, please refer to Andy's answer.

const App = () => {
  const changeAppColor = () => {
    let el = document.getElementById("root");
    if (el.style.backgroundColor === "red") {
      el.style.backgroundColor = "unset";
    } else {
      el.style.backgroundColor = "red";
    }
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      <button onClick={changeAppColor}>
        Change color
      </button>
    </div>
  );
}

ReactDOM.createRoot(
    document.getElementById("root")
).render(
    <App />
);
<div id='root'> </div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

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

Error message: After using gulp-npm-dist to copy only the dependency modules, the node module was not

I'm currently exploring different methods to package only the necessary node_modules dependencies for my project. After some research, I came across gulp-npm-dist and created a gulpfile.js. var gulp = require('gulp'); var npmDist = requir ...

Highlight the parent name in the menu when I am on the corresponding child page

Here is a snippet of a recursive function: function recursive($arrays, $out) { if (is_array($arrays)){ //$out .= "<ul>"; foreach($arrays as $parent => $data) { //if parent is empty if ($parent === '') { ...

There seems to be a problem with the text-to-speech API: It looks like there's a ReferenceError stating that

Currently, I am developing a program using the Quasar framework which is based on Vue and can be compiled for mobile using Cordova. However, I am encountering some issues when trying to run it on mobile. Below is the function causing problems: activat ...

Tips for accessing and modifying parent state resolve data within the onEnter function of a child state in a UI router

Within my ui-router state configuration, I have the following setup: Parent state $stateProvider .state('profile',{ url: '/profile', views: { 'contentFullRow': { ...

Looking to adjust the API response to fit the necessary JSON format for an Angular project?

A modification is needed in the API response to align with the required JSON format provided below. The current responses and the desired format are detailed for reference. Assistance is appreciated. The current representation of individual's data ne ...

Immediate display of collapsed/toggle menu in a Bootstrap navbar

I have created a bootstrap responsive navigation menu that collapses into a box when the page is resized. It's a standard menu with bootstrap, but I'm facing an issue where the menu automatically appears when the page gets small instead of needin ...

Stop Material-UI InputLabel from shifting to the top left corner of the Select element

I've been struggling to implement a true Placeholder functionality for the Material-UI Select component. It seems that using the placeholder prop on `<Select />` isn't working as expected, and I'm having issues with passing it to the i ...

Error encountered while compiling versus browsing in a ReactJS application

I am currently building my Reactjs application using sbt. Browser issue Uncaught SyntaxError: Unexpected token : Compilation error Parse Error: Line 2: Unexpected token = In C:\Users\martin\Documents\Web Projects\example-app&bs ...

Does Google's caching process differ when using <span> tags instead of <h> tags for headings?

Does the choice between using <span class="heading"> and <h> tags impact search engine optimization for Google? As I'm constructing a website, I decided to style the headings and subheadings with <span>. However, I began to wonder i ...

Can you provide a brief explanation for this bubble sort JavaScript code?

Can someone please explain to me what the line j<len-i is doing in this bubble sort code? I believe removing -i from that line will still make the program work properly, var arr=[3,5,4,7,8,9,30,0,-1]; function bubble_Sort(arr){ var len = arr.length, ...

Tips for adjusting the width of items within the Box element in Material UI React

I am utilizing React Material UI along with the Box component to style my form. In this scenario, I have 4 items in each row except for the last row where I need to display only 3 items with the last item filling the entire row by merging two elements toge ...

Firebase hosting adjusts the transparency of an element to 1% whenever it detects the presence of CSS opacity

I'm currently working on a website using Vue.js and Firebase. Everything runs smoothly locally, including a button with a desired low opacity. However, when I deploy the site to Firebase Hosting, the button's opacity inexplicably changes to 1% an ...

"Troubleshooting the slow loading of PDF files when using React's render-pdf feature

After creating a table with the ability for each row to generate and download a PDF using render-pdf npm, I encountered an issue. When the user clicks the download button, the PDF preview opens on a new page. However, there are problems with rendering as a ...

When the input CTRL+C is entered in the console, Node.js / JavaScript will output

I have a script that I use to restart another script. Here is the code snippet: catch(err){ console.log(err) webhook.send(`Error monitoring **www.-.com**, restarting monitor.`) await browser.close() await sleep(monitorDelay) return chec ...

Convert inline javascript into an external function and update the reference to `this`

I'm currently in the process of converting some inline JavaScript code triggered by a button's onclick event to a regular JavaScript function. In my previous implementation, I successfully used the "this" reference to remove a table column. Howe ...

Tips for integrating a hubspot form into a Next JS component

I've been attempting to integrate a HubSpot form into a Next.js component without success so far. I followed the guidelines mentioned here, but have yet to figure it out. Where exactly should I place the embed code? As a newcomer to the realms of Rea ...

Guide on how to retrieve a response from an API Route and integrate it into the client side of the app router within Next.js

Transitioning from Next.js 12 to 13 has been quite perplexing, especially when it comes to handling JSON data. Every time I attempt a fetch request, I find myself needing to refer back to documentation due to the confusion surrounding JSON. Is there anyone ...

Reorganize divisions using Bootstrap

I am exploring different ways to manage responsiveness through the reordering of divs. While I am aiming for a solution that is highly flexible, any suggestion would be appreciated. Desktop View: https://i.stack.imgur.com/boSOa.png Mobile View: https:// ...

Sending data from JavaScript to Jade templatesIs this alright?

Utilizing node.js, express, jade, and socket.io, I have successfully executed JavaScript code on the jade side. However, I am encountering difficulty in generating HTML output from the script block. Based on your feedback, I have updated my question to in ...

Tips for changing the size and color of SVG images in a NextJS application

Looking to customize the color and size of an svg image named "headset.svg". Prior to this, I used next/image: <Image src={'/headset.svg'} alt='logo' width={30} height={30} className='object-contain' /> The s ...