I've been working on adding dark mode to my header component, and I decided to use context API to manage it. However, I'm running into issues with

In my root component, RootApp.jsx handles the component tree:

import { Suspense } from 'react';
import { HashRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from '@/redux/store';
import PageLoader from '@/components/PageLoader';

import '@/style/app.css';
import '@/style/index.css';
import '@/style/tailwind.css'

import ERP_SODEOs from '@/apps/IdurarOs';
import { ThemeProvider } from '@/context/ThemeContext/ThemeContext'; // Import ThemeProvider

export default function RoutApp() {
  return (
    <Router>
      <Provider store={store}>
        <ThemeProvider>
          <Suspense fallback={<PageLoader />}>
            <ERP_SODEOs />
          </Suspense>
        </ThemeProvider>
      </Provider>
    </Router>
  );
}

Within <ERP_SODEOs>, there are multiple components. The main component handling the child components is ErpApp.jsx:


  return (
    <Layout hasSider>
      <Navigation onPathChange={handlePathChange} />

      {isMobile ? (
        <Layout style={{ marginLeft: 0 }}>
          <HeaderContent />
          <Content
            style={{
              margin: '40px auto 30px',
              overflow: 'initial',
              width: '100%',
              padding: '0 25px',
              maxWidth: 'none',
            }}
          >
            <AppRouter />
          </Content>
        </Layout>
      ) : (
        <Layout style={{ marginLeft: isNavMenuClose ? 100 : 220 }}>
          <HeaderContent currentPath={currentPath} />
          <Content
            style={{
              margin: '30px auto 30px',
              overflow: 'initial',
              width: '100%',
              padding: '0px 10px 0px 0px',
              maxWidth: isNavMenuClose ? 1700 : 1600,
            }}
          >
            <AppRouter />
          </Content>
        </Layout>
      )}
    </Layout>
  );
}

I am attempting to implement dark mode inside my HeaderContent.jsx using a custom CSS file imported globally. However, this implementation is not working as expected.

The dropdown button in HeaderContent allows users to change the theme of the application. When the user selects the "Dark" option, the header color should change. I have also created a context that can be used in other components. Additionally, I have updated the tsconfig file with darkMode: 'class'.

Answer №1

To enable dark mode feature using Context API and ensure its functionality throughout your application, including within the HeaderContent component, you must follow a series of steps to properly configure and utilize your ThemeContext. Here is a comprehensive guide to assist you in troubleshooting and implementing this feature:

Step 1: Establish the Theme Context Begin by creating a ThemeContext with a provider and a custom hook for easier usage.

ThemeContext.js

import React, { createContext, useState, useContext, useEffect } from 'react';

const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState(() => {
    // Retrieve the stored theme or default to 'light'
    const savedTheme = localStorage.getItem('theme');
    return savedTheme ? savedTheme : 'light';
  });

  const toggleTheme = (newTheme) => {
    setTheme(newTheme);
    localStorage.setItem('theme', newTheme);
  };

  useEffect(() => {
    // Apply the theme to the body class
    document.body.className = theme;
  }, [theme]);

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

export const useTheme = () => useContext(ThemeContext);

Step 2: Wrap Your Application with the Theme Provider Ensure that your ThemeProvider encapsulates your entire application to make the context available to all components.

RootApp.jsx

import { Suspense } from 'react';
import { HashRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from '@/redux/store';
import PageLoader from '@/components/PageLoader';

import '@/style/app.css';
import '@/style/index.css';
import '@/style/tailwind.css';

import ERP_SODEOs from '@/apps/IdurarOs';
import { ThemeProvider } from '@/context/ThemeContext/ThemeContext'; // Import ThemeProvider

export default function RootApp() {
  return (
    <Router>
      <Provider store={store}>
        <ThemeProvider>
          <Suspense fallback={<PageLoader />}>
            <ERP_SODEOs />
          </Suspense>
        </ThemeProvider>
      </Provider>
    </Router>
  );
}

Step 3: Utilize the Theme Context in HeaderContent You can now employ the useTheme hook to access and update the theme within your HeaderContent component.

HeaderContent.jsx

(The code for HeaderContent component remains the same)

Step 4: Implement Dark Mode Styles Lastly, ensure that your CSS includes the appropriate styles for both dark mode and light mode. Use a CSS class on the body element to manage this.

body.light {
  background-color: #ffffff;
  color: #000000;
}

body.dark {
  background-color: #1a1a1a;
  color: #ffffff;
}

In this method, the toggleTheme function adjusts the theme state and updates the local storage accordingly. The useEffect hook applies the selected theme by modifying the body class. The HeaderContent component utilizes the useTheme hook to access the current theme and apply appropriate styling.

By following these steps, you should ensure the successful operation of the dark mode functionality across your application.

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

The slider customization on Joomla is functioning perfectly on my local machine, but it seems to be encountering some issues on

Having recently started working on a Joomla website for the first time, I encountered some challenges when trying to add a slider module. Despite successfully implementing the slider on my local machine, I faced issues when transferring the code to the liv ...

Thumbnail image preview fails to display after preloading an image in dropzonejs

Currently, I have a form where users can input their name and upload an image (logo). The client side language being used is AngularJS with dropzonejs as the image upload library. When the user clicks on the 'Edit' button, I want them to see a pr ...

Adjust the height of the HTML overlay to span the entire visible page

I have a website that utilizes AJAX to load content dynamically. To enhance user experience, I implemented an overlay with a loading indicator during the loading process using jQuery and the jQuery BlockUI plugin. When invoking $(element).block(), everyth ...

I encountered an error message stating "Unexpected token {" while trying to import the module "express-fileupload"

Struggling to implement file uploading with NodeJS on Ubuntu, encountering errors. Upon adding const fileUpload = require('express-fileupload'); the app fails to compile, throwing this syntax error: 2|theproje | /home/asgeir/nodejs/first_test ...

Succession of Mongoose queries

One interesting feature of my model is the ability to chain queries like find(), limit(), and skip(). However, there arises a question: How can I apply the limit or skip function to the output of Model.find() if the returning value does not inherently cont ...

I am having trouble establishing a connection to the JavaScript MQTT server

Error Encountered: WebSocket Error 12031 - The Server Connection Was Reset In order to subscribe to MQTT messages from the user interface, the code below is being utilized. A Mosquitto broker is currently running on my local machine, with the IP address s ...

Combine the PHP table with the Javascript table

I am facing a challenge where I have a table in PHP and another table in Javascript. My goal is to combine the elements of the PHP table with the elements of the Javascript table. I attempted to achieve this using the push method: <?php $tabPHP=[&apos ...

Ways to eliminate dates from the text of listed items

Before finalizing their registration, users on our site are shown a review page. This panel displays all the items they have selected, creating a unique and variable list for each individual. However, each item in the list starts with a distracting date/ti ...

What is the best method to deliver static html assets to a node server that is being operated with nginx?

I am currently running a server using pm2 and nginx to serve up my React app. My goal is to have the server only respond to requests sent by the client, but when I try to access jwcuisine.io, I receive a "CANNOT GET /" message. I attempted to configure th ...

Reports of missing packages in the React Starter Kit have caused confusion among users

While I may be new to React/JS, I have a wide range of experience in different technologies, including some work with Angular/JS. Therefore, my encounter with the Node/JS ecosystem is not completely fresh. The journey began when I encountered a missing pe ...

"Mongo server is rejecting the connection, and the reason is unclear to me

I created a MongoDB model with the following structure:- var mongoose = require('mongoose'); const itemsModel = new mongoose.Schema({ _id: { type: String, }, userName: { type: String, required: true }, ...

Is there a way to update the input box value with a variable using jquery?

I am currently facing an issue with changing the value attribute of an input box in a form using jquery. Although I am able to change the value, it does not reflect in the outer html. Below is my current code snippet: $("a").click(function(event) { va ...

Is there a way to selectively load only the <head> content from AJAX data and update the current <head> element?

While attempting to retrieve the <head> content of data using AJAX and replace it with the current one, I am encountering errors and the code at the bottom is not functioning as expected. $('head').html($(data).find('head:first') ...

unable to format radio button list

Having trouble aligning the radiobutton list to the left of the label above. Here is the code snippet: <div style="border-radius: 10px;"> <div style="margin-bottom: 10px"></div> <asp:Panel ID="panel" runat="server"&g ...

Guide on closing a Bootstrap modal by clicking within the UI Grid in Angular

I have an Angular app written in TypeScript where I am utilizing the ui grid to present data within a bootstrap modal. My goal is to have the modal close when any of the columns in a grid row are clicked. Currently, I am not relying on $modal or $modalIn ...

Leverage JSON data in JavaScript

Having some trouble figuring out how to incorporate JSON values into my JS script. Any assistance would be greatly appreciated as I am still new to this! Below is the snippet of code where I need the values (lat and lon) to be inserted: var map; functio ...

What is the best way to achieve a sleek and seamless scrolling effect on a webpage?

Is there a way to improve the scrolling effect on my website using jQuery? I find that the default scrolling behavior in most browsers is jumpy and I'm hoping to achieve a more smooth and polished look. ...

Having trouble with my NodeJS POST route implementation with Axios

I encountered an issue with my Post route using axios. Upon clicking the button to create a new user, I received the following error message: (node:13901) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'username' of undefined ...

Extension for Chrome that switches between active and inactive modes

I have been attempting to create an extension that can toggle the functionality of another specific extension on and off. Despite numerous attempts, I have not been able to find a solution that works effectively. Essentially, my extension displays a popup ...

Creating a service function (constructor) in JavaScript

When working with AngularJs and calling a service method: app.service('nameService', function() { this.Service = function (){console.log('hello')} } You can then use this service (object) like so: nameService.Service() My question is, ...