我正在尝试创建一个简单的 Context 对象,它将在我的 Fresh/Preact 应用程序中保存一些全局状态。我遇到的问题是,当尝试渲染应用程序时,它会抛出错误:将循环结构转换为 JSON。我理解这个错误的含义以及它发生的原因(因为 AppContext.Provider 有一个对其自身的引用,这会在尝试对其进行字符串化时导致错误,因为 Fresh 使用服务器端渲染)。我不知道如何解决这个问题。我尝试过仅使用 Preact 信号来表示状态,但这会导致其他问题。我真正想要的是某种方法让 Context 的解决方案发挥作用,因为我很舒服地在 Next.JS 中使用它。
AppContext.tsx:
import { createContext } from "preact"
import { useContext, useState } from "preact/hooks"
export type Theme = "light" | "dark"
export type Language = "english" | "norsk"
interface IAppContext {
theme: Theme,
language: Language,
toggleTheme: () => void,
toggleLanguage: () => void
}
const AppContext = createContext<IAppContext>({
theme: "light",
language: "english",
toggleLanguage: () => {},
toggleTheme: () => {}
})
export const useAppContext = () => useContext(AppContext)
export default function AppContextProvider({ children }: any) {
const [theme, setTheme] = useState<Theme>("light")
const [language, setLanguage] = useState<Language>("english")
const toggleTheme = () => setTheme(_theme => _theme === "light" ? "dark" : "light")
const toggleLanguage = () => setLanguage(_language => _language === "english" ? "norsk" : "english")
const context: IAppContext = {
theme,
language,
toggleTheme,
toggleLanguage
}
return <AppContext.Provider value={context}>{children}</AppContext.Provider>
}
最佳答案
我最终放弃了 Context Hook 并使用信号。 我现在只需在需要的地方导入 AppContext:
import { Signal, signal } from "@preact/signals"
export type Theme = "light" | "dark"
export type Language = "english" | "norsk"
interface IAppContext {
theme: Signal<Theme>,
language: Signal<Language>,
toggleTheme: () => void,
toggleLanguage: () => void
}
const theme = signal<Theme>("light")
const language = signal<Language>("english")
const storedTheme = localStorage.getItem("theme") as Theme | null
if (storedTheme) {
theme.value = storedTheme
setCSSTheme(storedTheme)
}
function toggleTheme() {
const newTheme = theme.value = theme.value === "light" ? "dark" : "light"
theme.value = newTheme
localStorage.setItem("theme", newTheme)
setCSSTheme(newTheme)
}
function setCSSTheme(theme: Theme) {
const classList = document.documentElement.classList
classList.add(theme)
classList.remove(theme === "light" ? "dark" : "light")
}
const toggleLanguage = () => language.value = language.value === "english" ? "norsk" : "english"
export const AppContext: IAppContext = {
theme,
language,
toggleTheme,
toggleLanguage
}
关于deno - Preact/Fresh 上下文导致错误 : Converting circular structure to JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74066964/