skip to Main Content

I’m creating my first react app and I’m having some problems with the light and dark mode. When clicking the button to toggleLightDark function, it works as it saves the true or false state to the localstorage and that works fine. The problem is that when I refresh the page, for some reason when the "chattiny_darkmode" is true, the icon always comes back to the sun for some reason and I’m unable to figure that out. Thanks in advance.

const LightDarkMode = () => {
    const [darkMode, setDarkMode] = useState(false);

    useEffect(() => {
        const data = localStorage.getItem("chattiny_darkmode");

        if (data !== null) {
            setDarkMode(localStorage.getItem("chattiny_darkmode"));
        }
    }, []);

    const toggleLightDark = () => {
        if (darkMode === true) {
            setDarkMode(false);
            localStorage.setItem("chattiny_darkmode", false);
        } else {
            setDarkMode(true);
            localStorage.setItem("chattiny_darkmode", true);
        }
    };

    return (
        <div className="light-dark-mode">
            <button onClick={toggleLightDark}>
                <FaSun className={darkMode === true ? "hidden" : ""} />
                <FaMoon className={darkMode === true ? "" : "hidden"} />
            </button>
        </div>
    );
};

For example, when the page refresh. The value is true for the "chattiny_darkmode" key in the local storage however, the symbol is a sun instead of a moon for some reason.

2

Answers


  1. localStorage only stores string values. When you setItem("chattiny_darkmode", true), true is stringified so you’re actually storing "true". When you retrieve this value, it is still a string, and "true" !== true, so you get day mode.

    You can convert the value back using e.g. JSON.parse(..), or simply comparing to "true".

    Incidentally, you may consider initialising darkMode directly from localStorage rather than updating it using useEffect. This is fine here because getItem(..) is synchronous.

    const LightDarkMode = () => {
        const [darkMode, setDarkMode] = useState(() =>
            localStorage.getItem("chattiny_darkmode") === "true"
        );
    
        const toggleLightDark = () => {
            if (darkMode === true) {
                setDarkMode(false);
                localStorage.setItem("chattiny_darkmode", "false");
            } else {
                setDarkMode(true);
                localStorage.setItem("chattiny_darkmode", "true");
            }
        };
        ...
    };
    
    Login or Signup to reply.
  2. Firstly, I would use the same type for the state and the localstorage data structures.

    Now, the syntax of the setItem is as follows

    setItem(keyName, keyValue)
    

    Parameters

    keyName
    A string containing the name of the key you want to create/update.

    keyValue
    A string containing the value you want to give the key you are creating/updating.

    So, if you replace your false/true boolean with a string equivalent, that will work for you.

    Something irrelevant from the question, I do not think storing the dark/light mode for a user in the localstorage is the best option that you have. If the user uses another device to access your website, they will need to reset the dark/light mode.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search