返回

如何实现 SSR 下的暗黑模式,同时确保页面不闪动?

前端

了解如何使用 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 样式表加载完成后再切换暗黑模式。