Search code examples
javascriptreactjsif-statementgettime

Using Conditions cause React render limit error


I've made a dark mode function. There are using checkbox and getting current hour to change this mode. When I write a traditional If statement it cause an error of render limits (like stack overflow).

Here's my code:

const curTime = new Date();
let t = curTime.getHours().valueOf();
const [isNight, setDarkMode] = useState(false);

if (t >= 6 && t <= 19) {
    document.documentElement.classList.remove("dark-mode");
    setDarkMode(false);
} else {
    document.documentElement.classList.add("dark-mode");
    setDarkMode(true);
}

const handleChecked = e => {
    if (e.target.checked === true) {
        document.documentElement.classList.add("dark-mode");
        setDarkMode(true);
    } else {
        document.documentElement.classList.remove("dark-mode");
        setDarkMode(false);
    }
};

<input id="myCheck" type="checkbox" onChange={handleChecked} defaultChecked={isNight} />

I can't find a solution from an Internet.

I think the answer would be using an UseEffect method but I don't really know how to use it in my situation. Or this checkbox could cause this infinite changing values?

Can you help me with this?


Solution

  • In React-style I would do it like this:

     import React, { useState, useEffect } from "react";
    
    const App = () => {
      const [isNight, setDarkMode] = useState(false);
    
      useEffect(() => {
        let t = new Date().getHours().valueOf();
        setDarkMode(t < 6 || t > 19);
      }, []);
    
      return (
        <div className={isNight ? "dark-mode" : "light-mode"}>
          <div>{isNight ? "dark-mode" : "light-mode"}</div>
          <input
            type="checkbox"
            onChange={(e) => setDarkMode(e.target.checked)}
            checked={isNight}
            name="darkModeInput"
          />
          <label htmlFor="darkModeInput">Switch dark mode</label>
        </div>
      );
    };
    
    export default App;