如何实现 SSR 下的暗黑模式,同时确保页面不闪动?
2023-10-05 23:35:10
了解如何使用 React 在 SSR 模式下实现暗黑模式,并确保页面在切换模式时不会出现闪动的情况。
从 React 最新文档中学习 SSR 下如何使用暗黑模式
React 最新版本的文档已经上线很久了,采用了 Next.js 开发。支持在线编辑,暗黑等相关功能。那么 react 是如何实现 SSR 下暗黑模式同时保证页面不闪动的呢?🤔
在 Next.js 中,支持两种暗黑模式设置方法。我们可以分别了解一下。
1. 使用 CSS 变量
在你的 global.css
文件中,你可以定义一个 CSS 变量来控制暗黑模式。例如:
:root {
--color-background: #fff;
--color-text: #000;
}
/* 暗黑模式 */
.dark {
--color-background: #000;
--color-text: #fff;
}
然后,你可以使用这些变量来样式化你的组件。例如:
const MyComponent = () => (
<div className="my-component">
<p style={{ color: 'var(--color-text)' }}>Hello, world!</p>
</div>
);
当你在用户切换到暗黑模式时,这些变量的值将自动更新,并且你的组件将相应地重新渲染。
2. 使用 context API
你也可以使用 React 的 context API 来管理暗黑模式状态。为此,你需要创建一个 context 对象,并在你的组件中使用它。例如:
const DarkModeContext = React.createContext(false);
const DarkModeProvider = ({ children }) => {
const [darkMode, setDarkMode] = React.useState(false);
return (
<DarkModeContext.Provider value={{ darkMode, setDarkMode }}>
{children}
</DarkModeContext.Provider>
);
};
const MyComponent = () => {
const { darkMode } = React.useContext(DarkModeContext);
return (
<div className="my-component">
<p style={{ color: darkMode ? '#fff' : '#000' }}>Hello, world!</p>
</div>
);
};
然后,你可以在你的组件中使用 useContext
hook 来访问 darkMode
状态,并根据它的值来样式化你的组件。
避免页面闪动
在 SSR 模式下,如果你在页面加载时切换暗黑模式,可能会出现页面闪动的现象。这是因为在页面加载时,服务器端渲染的 HTML 使用的是默认的样式。然后,当客户端接管时,它会重新渲染页面,并应用暗黑模式的样式。这就会导致页面出现闪动。
为了避免这种闪动,你可以使用以下两种方法之一:
- 在服务器端渲染的 HTML 中使用暗黑模式的样式。
- 在客户端等待 CSS 样式表加载完成后再切换暗黑模式。
在服务器端渲染的 HTML 中使用暗黑模式的样式
如果你使用的是 Next.js,你可以通过修改 _document.js
文件来实现这一点。例如:
import Document, { Html, Head, Main, NextScript } from 'next/document';
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html>
<Head>
<style>{`
:root {
--color-background: #000;
--color-text: #fff;
}
`}</style>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
在客户端等待 CSS 样式表加载完成后再切换暗黑模式
如果你不使用 Next.js,或者你不想修改 _document.js
文件,你可以使用以下方法来实现这一点:
document.addEventListener('DOMContentLoaded', () => {
// 等待 CSS 样式表加载完成后
setTimeout(() => {
// 切换暗黑模式
document.body.classList.add('dark');
}, 100);
});
结语
使用 React 在 SSR 模式下实现暗黑模式其实非常简单。你可以通过使用 CSS 变量或 context API 来管理暗黑模式状态。为了避免页面闪动,你可以在服务器端渲染的 HTML 中使用暗黑模式的样式,或者在客户端等待 CSS 样式表加载完成后再切换暗黑模式。