Challenge with Updating React Components When Switching Themes

In my React application, I'm facing a challenge with theme switching. There are two themes available: Theme One and Theme Two. To dynamically load theme components, lazy loading has been implemented based on the selected theme.

Each theme has its own styling for a common button class. In Theme One, the button appears blue, while in Theme Two, it is brown.

The issue arises when switching themes using a button. Initially, when moving from Theme One to Theme Two, the button color changes correctly from brown to blue. However, upon returning to Theme One, the button color fails to revert to brown as expected. Subsequent theme switches also do not update the button color accordingly.

For code reference, please visit: here

// App.js
import React, { createContext, useState, startTransition, useEffect } from "react";
// Lazy load themes
const ThemeOne = React.lazy(() => import("./themes/theme-one"));
const ThemeTwo = React.lazy(() => import("./themes/theme-two"));

export const MawbThemeContext = createContext({ _theme: "" });

const App = () => {
  const [_theme, setTheme] = useState("themeOne");

  const handleChangeTheme = () => {
    startTransition(() => {
      if (_theme === "themeOne") {
        setTheme("themeTwo");
      } else {
        setTheme("themeOne");
      }
    });
  };

  let themeComponent;
  if (_theme === "themeOne") {
    themeComponent = <ThemeOne handleChangeTheme={handleChangeTheme} />;
  } else if (_theme === "themeTwo") {
    themeComponent = <ThemeTwo handleChangeTheme={handleChangeTheme} />;
  } else {
    themeComponent = <ThemeTwo handleChangeTheme={handleChangeTheme} />;
  }

  useEffect(() => {
    startTransition(() => {
      console.log("transition", _theme); // Ensure theme is changing correctly
    });
  }, [_theme]);

  return (
    <>
      <MawbThemeContext.Provider value={{ _theme }}>
        {themeComponent}
      </MawbThemeContext.Provider>
    </>
  );
};

export default App;

I would appreciate any insights into why the theme updates are not being reflected correctly, especially when transitioning between themes multiple times.

Answer №1

The issue arises from the css import statements within your components.

import "../scss/index.theme.one.scss";
import "../scss/index.theme.two.scss";

If you examine the generated HTML in your application, you will notice the following behavior.

When your app initially launches, only the ThemeOne component is invoked, so upon inspecting the css, you will see that only the first one is loaded:

https://i.sstatic.net/M6365ukp.png

However, when you switch themes, the second import statement is triggered, causing the second css file to be loaded:

https://i.sstatic.net/WxT0ZKAw.png

Subsequently, regardless of how many times you switch themes, the second css file takes precedence over the first one, resulting in the absence of your desired brown button.

To resolve this issue, you must manage the context passed through your component.

For instance, utilize hooks to access the current context and apply the appropriate css properties. A helpful example can be found here

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

Struggling to constrain a TextField component from material-ui and encountering an issue with the inputRef

Currently, I am attempting to restrict the length of an autocomplete textfield within my project. However, when I apply InputProps={{ maxLength: 2 }}, it throws an error stating that my inputRef.current is null. Even though I have set the ref in the inputR ...

The data displayed in the <span> element isn't reflecting the response from the loaded page, despite being visible in Firebug

I have encountered a problem while trying to load a signup.php page into a div on my main page. All the elements (forms, JavaScript, etc.) function correctly in the loaded page, except for one issue - I cannot get the response from the PHP script to displa ...

Troubleshooting: Issues with jQuery's clone() function

I'm facing an issue with the code below. It works correctly when I use td instead of p. $(document).ready(function() { $("button").click(function() { $("th:contains('2G Band') ~ p").clone().appendTo("#2g"); }); }); <script src= ...

Unable to adjust font for headings using CSS and Bootstrap

Looking to expand my skills in HTML and CSS, I've encountered a bit of a hiccup. Utilizing Bootstrap for my webpage, here's the simplified version of what I have so far: index.html: <!DOCTYPE html> <html> <head> <lin ...

Is there a way for me to modify the position of a cursor graphic?

Similar Question: Custom cursor interaction point - CSS / JQuery I've been experimenting with changing the image of the mouse pointer by using the CSS cursor property ("cursor: url(images/target.png), crosshair;") and have observed that when a us ...

How to prevent useEffect from rendering the form script twice during loading?

On my next.js site, I am utilizing a HubSpot form that I would like to render only once on page load. Currently, the form is rendering twice which is not the desired outcome. How can I modify the code to ensure the form renders only on page load? I attemp ...

Tips for keeping my wordpress menu at the forefront

This piece of code is responsible for controlling the main menu on my website. Currently, it's set up so that when I scroll down, the menu disappears, and when scrolling up, it reappears. However, I would like the menu to always remain displayed at t ...

Encountering the error message "TypeError: Cannot access property 'Token' of undefined" while compiling fm.liveswitch

The fm.liveswitch JavaScript Software Development Kit (SDK) is designed for use with both clients and your own backend "app server". It functions smoothly in the frontend thanks to webpack and babel. However, the same import statement: import liveswitch fr ...

Adjusting the brightness of colors using JavaScript

I am looking for a way to return different color tones for a specific color using JavaScript. For example, if I have the color code #4a4a4a, I want to be able to return #494949 and #666464. If there is a package or method that can achieve this, please sugg ...

Error: The function concat() is not valid for messagesRef.current

I'm currently developing an app that enables users to interact with AI by asking questions related to the uploaded PDF file. However, I've encountered a problem while interacting with AI on the client side - I keep receiving the error 'TypeE ...

Bordering the isotopes

Currently, I am utilizing a plugin that involves the isotope filter library. By setting the width to 33.33%, my list elements are organized into 3 columns. I am trying to specify the middle column to have side borders. However, whenever I click on the filt ...

Determine the value from an object in the view by evaluating a string in dot notation

Seeking assistance with a recurring issue I've encountered lately. Imagine having two objects in AngularJS: $scope.fields = ['info.name', 'info.category', 'rate.health'] $scope.rows = [{ info: { name: "Apple", cate ...

What is the best way to place a button within a line of text

I am trying to achieve a layout similar to this: -------------------button------------------ I can add text inside the line, but it doesn't look good when I add a button. Any suggestions on how I can improve this? ...

Troubleshooting Generic Problems in Fastify with TypeScript

I am currently in the process of creating a REST API using Fastify, and I have encountered a TypeScript error that is causing some trouble: An incompatible type error has occurred while trying to add a handler for the 'generateQrCode' route. The ...

Utilizing async/await as a module function: A comprehensive guide

Express Route: const express=require('express'); const router=express.Router(); const trackRepo=require('../model/track'); router.post('/live',function(req,res){ const time=1439832167; const list=trackRepo.getAlerts ...

Integrating content from a separate PHP page into the main index PHP page

I can't seem to get the #container1 div on my index.php page to load with the content from another #container2 div on page1.php. It's frustrating because I've checked my file hierarchy and everything seems correct. This is how my files are ...

What is the most efficient way to transmit an HTML document element from a client to a server in Node JS

I am attempting to capture a snapshot of my client-side document object and send it to the Node.js server. However, when I try to convert it into a string using: JSON.stringify(document.documentElement) I encounter an issue where it becomes an empty obje ...

How to include a key-value pair to a JSON object within an array using JavaScript

I am looking to include the following functionality in the JSON data provided below: "Check if the key name default exists, and if it does, add another key within the same object => ("pin" : 91)." I have attempted to achieve this using the code snippet ...

Techniques for capturing Django's output from an Ajax request

I've been trying to utilize Ajax for converting my form data to JSON and sending it to my Django view. However, I'm encountering an issue where after successful processing in the view, I am returning a template response with some context data tha ...

What is the method for retrieving all 'name' values within a JSON array?

I am currently working on a project using Angular and I have a JSON file. I need to extract all the 'name' values from the array. Ideally, the output should look something like this: ['Sony', 'Apple', 'Sony'] JSON: ...