dea*_*904 1 javascript reactjs mobx next.js tailwind-css
我有一个黑暗模式组件,它是太阳和月亮图标之间的简单切换。
import { observer } from 'mobx-react'
import { MoonIcon, SunIcon } from '@heroicons/react/solid'
import { useStore } from '@/store/index'
export const DarkMode = observer(() => {
const { theme, setTheme, isPersisting } = useStore()
if (!isPersisting) return null
return (
<>
{theme === 'dark' && (
<button
className="fixed bottom-12 right-12 focus:outline-none"
title="Activate light mode"
onClick={() => {
setTheme('light')
}}
>
<MoonIcon className="w-8 h-8" />
</button>
)}
{theme === 'light' && (
<button
className="fixed bottom-12 right-12 focus:outline-none"
title="Activate dark mode"
onClick={() => {
setTheme('dark')
}}
>
<SunIcon className="w-8 h-8" />
</button>
)}
</>
)
})
Run Code Online (Sandbox Code Playgroud)
我正在使用 MobX 来跟踪我的theme&mobx-persist-store将数据保存在localStorage.
import { makeObservable, observable, action } from 'mobx'
import { makePersistable, isPersisting, clearPersistedStore } from 'mobx-persist-store'
import type { Theme, IStore } from '@/types/index'
const name = 'Store'
const IS_SERVER = typeof window === 'undefined'
export class Store implements IStore {
theme: Theme = 'light'
constructor() {
makeObservable(this, {
theme: observable,
setTheme: action.bound,
reset: action.bound,
})
if (!IS_SERVER) {
makePersistable(this, { name, properties: ['theme'], storage: window.localStorage })
}
}
setTheme(theme: Theme) {
this.theme = theme
}
get isPersisting() {
return isPersisting(this)
}
async reset() {
if (!IS_SERVER) await clearPersistedStore(this)
}
}
Run Code Online (Sandbox Code Playgroud)
当用户在深色模式组件中选择主题时,我将添加dark类。htmldark
import React from 'react'
import { AppProps } from 'next/app'
import Head from 'next/head'
import { observer } from 'mobx-react'
import useSystemTheme from 'use-system-theme'
import { useStore } from '@/store/index'
import '@/components/NProgress'
import 'nprogress/nprogress.css'
import '@/styles/index.css'
const MyApp = ({ Component, pageProps }: AppProps) => {
const systemTheme = useSystemTheme()
const { theme, setTheme } = useStore()
React.useEffect(() => {
const isDarkTheme = theme === 'dark' || (systemTheme === 'dark' && theme !== 'light')
if (isDarkTheme) {
document.documentElement.classList.add('dark')
setTheme('dark')
} else {
document.documentElement.classList.remove('dark')
setTheme('light')
}
}, [theme, systemTheme])
return (
<>
<Component {...pageProps} />
</>
)
}
export default observer(MyApp)
Run Code Online (Sandbox Code Playgroud)
我仍然收到一条错误消息:
import { observer } from 'mobx-react'
import { MoonIcon, SunIcon } from '@heroicons/react/solid'
import { useStore } from '@/store/index'
export const DarkMode = observer(() => {
const { theme, setTheme, isPersisting } = useStore()
if (!isPersisting) return null
return (
<>
{theme === 'dark' && (
<button
className="fixed bottom-12 right-12 focus:outline-none"
title="Activate light mode"
onClick={() => {
setTheme('light')
}}
>
<MoonIcon className="w-8 h-8" />
</button>
)}
{theme === 'light' && (
<button
className="fixed bottom-12 right-12 focus:outline-none"
title="Activate dark mode"
onClick={() => {
setTheme('dark')
}}
>
<SunIcon className="w-8 h-8" />
</button>
)}
</>
)
})
Run Code Online (Sandbox Code Playgroud)
的button事件onClick处理程序从 DOM 本身消失。
有趣的是,它过去可以在 MacOS 上运行,但不能在 Windows 上运行。我克隆了同一个项目。有什么问题吗?
我在深色/浅色主题实现过程中遇到了同样的问题,但根据deadcoder0904的评论解决了它。
就我而言,该应用程序是使用next-themes库构建的。
由于此错误与SSR有关,因此需要确认组件是否安装在前端侧。
import { useEffect, useState } from 'react';
import { useTheme } from 'next-themes';
const ThemeToggler = () => {
const { theme, setTheme } = useTheme()
const [hasMounted, setHasMounted] = useState(false);
useEffect(() => setHasMounted(true));
// this line is the key to avoid the error.
if (!hasMounted) return null;
return (
<div>
The current theme is: {theme}
<button onClick={() => setTheme('light')}>Light Mode</button>
<button onClick={() => setTheme('dark')}>Dark Mode</button>
</div>
)
}
export default ThemeToggler;
Run Code Online (Sandbox Code Playgroud)
希望这对您有帮助。
| 归档时间: |
|
| 查看次数: |
1879 次 |
| 最近记录: |