刷新后State和localStorage数据不同

发布于 01-11 14:55 字数 1370 浏览 2 评论 0原文

所以我对状态和本地存储有疑问。确切地说,每当我将对象嵌套在themes.dark和themes.light中时,动态代码块中的结果在刷新后会有所不同,即使localStorage数据实际上是正确的。

import { useState, useEffect } from "react";
import store from "store2";
import "./styles.css";

const themes = {
  dark: {
    theme: "dark"
  },
  light: {
    theme: "light"
  }
};

export default function App() {
  const defaultDarkTheme = window.matchMedia("(prefers-color-scheme:dark)")
    .matches
    ? themes.dark
    : themes.light;
  const [theme, setTheme] = useState(store.get("theme") || defaultDarkTheme);

  useEffect(() => {
    store.set("theme", theme);
  }, [theme]);

  return (
    <>
      <div
        className="App"
        onClick={() =>
          theme === themes.dark ? setTheme(themes.light) : setTheme(themes.dark)
        }
      >
        {JSON.stringify(theme)}
      </div>
      {theme === themes.dark
        ? JSON.stringify(themes.dark)
        : JSON.stringify(themes.light)}
    </>
  );
}

刷新前

在此处输入图像描述

刷新后:

在此处输入图像描述

这是一个很大的问题,因为刷新后而不是生成黑暗模式的内容生成轻量级的内容。

So I have a problem with state and localStorage. To be exact, whenever I nest the objects inside of the themes.dark and themes.light the results in dynamic codeblock differ after refresh even though the localStorage data is in fact correct.

import { useState, useEffect } from "react";
import store from "store2";
import "./styles.css";

const themes = {
  dark: {
    theme: "dark"
  },
  light: {
    theme: "light"
  }
};

export default function App() {
  const defaultDarkTheme = window.matchMedia("(prefers-color-scheme:dark)")
    .matches
    ? themes.dark
    : themes.light;
  const [theme, setTheme] = useState(store.get("theme") || defaultDarkTheme);

  useEffect(() => {
    store.set("theme", theme);
  }, [theme]);

  return (
    <>
      <div
        className="App"
        onClick={() =>
          theme === themes.dark ? setTheme(themes.light) : setTheme(themes.dark)
        }
      >
        {JSON.stringify(theme)}
      </div>
      {theme === themes.dark
        ? JSON.stringify(themes.dark)
        : JSON.stringify(themes.light)}
    </>
  );
}

Before refresh :

enter image description here

After refresh :

enter image description here

It's pretty problematic since after refresh instead of generating the content for dark mode it generates the content for the light one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你在我安2025-01-18 14:55:32

我认为这是因为你的 useEffect 钩子。

 useEffect(() => {
   store.set("theme", theme);
 }, [theme]);

我认为您的 useEffect 在从 localStorage 获取数据之前运行。我不确定这只是一种预感。

I think it is because of your useEffect hook.

 useEffect(() => {
   store.set("theme", theme);
 }, [theme]);

I think your useEffect runs before it gets the data from the localStorage. I'm not sure this is just a hunch.

冰雪之触2025-01-18 14:55:32

您的问题不在于状态或存储。如果您在声明状态后添加以下行并在将其更改为黑暗后刷新页面,您将看到您的问题。
console.log(theme, theme.dark, theme === theme.dark)

Javascript 仅在两个对象引用完全相同的对象时才判定它们相等。但是,当您从商店获取主题对象时,它与您之前定义的 theme.dark 对象并不完全相同。

有多种方法可以处理这样的场景,但我认为如果您比较对象的某些字符串属性,这将是最简单的,例如,

theme.theme === themes.dark.theme
        ? JSON.stringify(themes.dark)
        : JSON.stringify(themes.light)

或者您可以在主题对象上定义一个唯一标识符属性,您可以用它来比较theme.theme 或者如果你真的想比较对象,你可以这样做

JSON.stringify(theme) === JSON.stringify(themes.dark)
        ? JSON.stringify(themes.dark)
        : JSON.stringify(themes.light)

Your problem is not with state or the storage. You will see your problem if you add the following line after declaring your state and refresh the page after changing it to dark.
console.log(theme, themes.dark, theme === themes.dark)

Javascript only decides that two objects are equal if they refer to the exact same object. However when you get your theme object from the store, it is not the exact same object as the themes.dark object you've defined earlier.

There are multiple ways to handle a scenario like this, but I think it would be simplest if you compare some string properties of the objects, for example,

theme.theme === themes.dark.theme
        ? JSON.stringify(themes.dark)
        : JSON.stringify(themes.light)

alternatively you could define a unique identifier property on your theme object which you can use to compare instead of theme.theme or if you really want to compare the objects you could do something like

JSON.stringify(theme) === JSON.stringify(themes.dark)
        ? JSON.stringify(themes.dark)
        : JSON.stringify(themes.light)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文