The dark mode class in Next.js/React does not take effect until a local change is made

I've been diving into a helpful tutorial on implementing dark mode toggle in my project. The tutorial uses react-toggle and can be found here. Everything seems to be working fine except for one issue that arises on the initial page load.

When the browser has 'prefers-color-scheme: dark', the dark mode toggle doesn't receive the 'react-toggle--checked' class until I make a local change in VSCode and save it. Only then does the class get applied properly.

Before saving: https://i.sstatic.net/aOAho.png

After saving: https://i.sstatic.net/9RX9O.png

I'm puzzled as to why this behavior is occurring. The initial value of 'isDark' is true, hence the Toggle's 'checked' value should also be true and trigger the application of the 'react-toggle--checked' class. Why does making a local change in the editor and saving fix this issue?

The technologies being used are Next.js and React.

useColorScheme.js


import { useEffect, useMemo } from 'react'
import { useMediaQuery } from 'react-responsive'
import createPersistedState from 'use-persisted-state'

const useColorSchemeState = createPersistedState('colorScheme')

export function useColorScheme() {
  const systemPrefersDark = useMediaQuery(
    {
      query: '(prefers-color-scheme: dark)',
    },
    undefined,
  );

  const [isDark, setIsDark] = useColorSchemeState()

  const value = useMemo(() => isDark === undefined ? !!systemPrefersDark : isDark,
    [isDark, systemPrefersDark])

  useEffect(() => {
    if (value) {
      document.body.classList.add('dark')
    } else {
      document.body.classList.remove('dark')
    }
  }, [value])

  return {
    isDark: value,
    setIsDark
  }
}

ColorSchemeToggle.js


import Toggle from 'react-toggle'
import { useColorScheme } from './useColorScheme'

// Styles
import 'react-toggle/style.css'

const ColorSchemeToggle = () => {
    const { isDark, setIsDark } = useColorScheme()

    return (
        <Toggle
            checked={isDark}
            onChange={({ target }) => setIsDark(target.checked)}
            aria-label='Dark mode toggle'
            className={`dark-mode-toggle`}
        />
    )
}

export default ColorSchemeToggle

Answer №1

It seems that the usepersistedstate library utilizes localstorage as its default storage mechanism.

Visit this link for more information

The use-persisted-state library functions as a factory rather than a hook itself. It requires a storage key and optional storage provider (default = localStorage) to return a hook that can be seamlessly integrated as a replacement for useState.

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

Clicking within the text activates the dropdown menu, but clicking outside the text does not

My custom drop down menu is not functioning properly. When I click on the text, it successfully links to another place, but when I click beside the text, it does not link. Can you please help me identify what's wrong here? Your assistance would be gre ...

designing a responsive form in the mobile environment

I have implemented a search form on my website with a button inside the text box. It works fine on desktop, but when I switch to mobile view, the positioning is off. I am currently using absolute positioning for the button to give it a fixed position. Is t ...

Creating a dynamic progress bar that scrolls for multiple elements

I am currently working on implementing a scrolling progress bar to show users how much of an article within a div they have read. For reference, something similar can be seen on this site. I have created my custom progress bar and coded it on fiddle, whe ...

React application encountering issues with the use of Redux actions within a custom module

I have been facing a problem with my util module. It seems that when I try to use a Redux action, it does not function as expected. import {openloading} from '../actions/loading' export default function (e) { openloading(e.font); } Interest ...

Asynchronous data fetching with React Hook useEffect does not properly populate the tooltip in Material UI component

After using useEffect to fetch data, I encountered a problem in passing the data to my component. Here is some of my code: User Data Types (UPDATED) export interface IUser { display_name: string; id: string; images: Image[]; } expo ...

Accessing Github REST API with Next-auth token

Looking to enable user login and retrieve specific user data using the Github REST API, such as repositories and issues. After successfully implementing the login feature, I encountered an obstacle with the Github REST API that requires a token for endpoi ...

Development of a custom waterfall toolbar design using MUI framework

I've been working with a setup similar to the one found here: https://codesandbox.io/s/1op5mqq9oq By clicking on the checkboxes, the <Toolbar /> is displayed. As you scroll down the page, the <Toolbar /> remains fixed at the top and even ...

Elevation Ratio

Is there a way to make the height of the textarea in my demo always be 50% of the frame's height, even when resizing the frame? Currently, the textarea's height does not adjust dynamically. How can I achieve this? html, body { line-heigh ...

Encountering a roadblock when attempting to redirect to a different page within a

I am facing an issue with my React page. When I click a button, the method studentApproval() is called successfully. However, after this method runs, I am trying to redirect to another page but it doesn't seem to be working. How can I resolve this red ...

retain focus even after using .blur()

Currently, I am implementing a form submission using AJAX. The form consists of only one input field and the submit button is hidden. My aim is to ensure that when the user hits the enter key, the input field does not lose its focus. Here's the code s ...

I have configured my CSS styles in the module.css file of my Next.js application, but unfortunately, they are not being applied

I recently developed a nextjs with electron template application: Here is the link to my code on CodeSandbox: https://codesandbox.io/s/sx6qfm In my code, I have defined CSS classes in VscodeLayout.module.css: .container { width: '100%'; he ...

Using the React API to fetch data

Just starting out with React and APIs, I decided to fetch data from a MongoDB API. The data is being logged correctly in the console, but I'm having trouble rendering it. import React from 'react'; class Api extends React.Component { comp ...

What is the best way to position href text on the top of a rectangular div box?

Whenever I try to position the text above the rectangle, it disables the link. How can I resolve this issue? Additionally, when attempting to change the color of the "San Diego" text, I'm unable to adjust its position. Just a heads up, I am new to HT ...

What is the best way to showcase my subscription form on a web browser?

I am encountering an issue with my code. My goal is to generate a subscribe form modal. Although I have incorporated the subscribe form in my HTML document, upon running the code in the browser, the subscribe section is not visible. Can anyone offer assist ...

Mixing strings with missing slashes in links

console.log(mylink) When using the console to log mylink, the expected result is a normal link like http://example.com/something.jpg. I tried concatenating it as shown below: var html = '<div id="head" style="background:linear-gradient(rgba(0, 0 ...

improving the resolution of images on iPhone 4 from 72ppi to 326ppi

I've been exploring ways to improve the quality of buttons in my mobile design. Currently, my navigation buttons are in a 72ppi PNG sprite and I also have another set at 326ppi. I've heard that iPhone4 can automatically choose the higher resoluti ...

Ways to execute a function when a button is clicked with a shared variable?

When creating buttons in HTML to control video speed, I encountered a strange issue. After successfully implementing the buttons for one video, they only worked on a second video and had no impact on the first one. Deleting the second video seemed to resol ...

Validating your tel hyperlink with HTML5 W3C standards is essential for

Hey there! I have a question about adding telephone links to the numbers on my website. How can I ensure that it passes W3C validation successfully? Currently, when using this syntax: <a href="tel: 0141 123456">0141 123456</a> I am getting th ...

What causes an image background to take precedence over the background color of Bootstrap buttons?

Why is the CSS overriding the bootstrap button background styling and making it transparent instead of the default color? For example, if I have a button with the following styling in my document that sets the background-image of the entire body to an ima ...

Ensure that the columns are consistently displayed on a single row

On larger screens, everything displays correctly. However, when viewing on a phone, the issue arises. I want these two columns to always stay on one row, but currently they stack on mobile devices. How can I ensure that they resize and remain on the same ...