반응형

 

🚀 다크 모드 새로고침 시 화면 깜빡임

Next.js 프로젝트를 진행하면서 다크 모드를 개발하게 되었는데 다크 모드 상태에서 새로고침 시 흰 화면이 보였다가 어두운 화면으로 바뀌어서 깜빡이는 현상을 발견하였고 이는 UX(사용자 경험)적으로 마이너스가 될 수 도 있을 것 같아서 해결방법을 알아봤습니다.

 

 

📋 다크 모드 코드

ToggleTheme.jsx

import React, { useEffect, useCallback } from "react";

const ToggleTheme = ({ changeTheme }) => {
  const setDark = useCallback(() => {
    localStorage.setItem("theme", "Dark");
    document.documentElement.setAttribute("data-theme", "Dark");
    if (changeTheme !== undefined) changeTheme();
  }, [changeTheme]);

  const setLight = () => {
    localStorage.setItem("theme", "Light");
    document.documentElement.setAttribute("data-theme", "Light");
    if (changeTheme !== undefined) changeTheme();
  };

  const toggleTheme = (e) => {
    if (e.target.checked) {
      setDark();
    } else {
      setLight();
    }
  };
  const storedTheme = localStorage.getItem("theme");

  const prefersDark =
    window.matchMedia &&
    window.matchMedia("(prefers-color-scheme: Dark)").matches;

  const defaultDark =
    storedTheme === "Dark" || (storedTheme === null && prefersDark);

  useEffect(() => {
    if (defaultDark) {
      setDark();
    }
  }, [defaultDark, setDark]);

  return (
    <input
      type="checkbox"
      id="checkbox"
      onChange={toggleTheme}
      defaultChecked={defaultDark}
    />
  );
};

export default ToggleTheme;

 

Test.jsx

import React from "react";
import styled from "@emotion/styled";
import dynamic from "next/dynamic";

const ToggleTheme = dynamic(() => import("@/components/common/ToggleTheme"), {
  ssr: false,
});

function Test() {
  return (
    <Container>
      <Title>다크 모드</Title>
      <ToggleTheme></ToggleTheme>
    </Container>
  );
}

export default Test;

const Container = styled.div`
  width: 300px;
  height: 100px;
  margin: 100px auto;
  text-align: center;
`;

const Title = styled.h1`
  font-size: 50px;
`;

 

global.scss

* {
  color: var(--font-color);
  background-color: var(--background-color);
  box-sizing: border-box;
}

:root {
  --font-color: #1d212c;
  --background-color: #ffffff;
}

[data-theme="Dark"] {
  --font-color: #ffffff;
  --background-color: #1d212c;
}

 

새로고침 시 흰색 화면이 나타나 깜빡임

위의 gif처럼 새로고침 시 화면이 번쩍이는 현상을 확인할 수 있습니다.

 

 

💡 해결 방법

테마를 변경하는 과정이 DOM 트리가 구성된 후 자바스크립트 파일을 파싱 한 후에 이루어졌기 때문에 처음 흰 화면이 렌더링 되고 그다음 어두운 화면이 렌더링 되어 깜빡임 현상이 발생했던 것입니다. 따라서 테마를 설정하는 시점이 스타일시트를 불러오고, DOM트리가 구성되기 전에 결정되어야 하므로 html 파일의 head에 script 태그로 dangerouslySetInnerHTML를 아래와 같이 설정해주면 화면 깜빡임 현상을 해결할 수 있습니다.

<script
  dangerouslySetInnerHTML={{
    __html: `
              const theme = localStorage.getItem("theme");
              document.documentElement.setAttribute("data-theme", theme);
              console.log(theme);
            `,
  }}
></script>;

 

pages/_document.js

import { Html, Head, Main, NextScript } from "next/document";

function Document() {
  return (
    <Html>
      <Head>
        <script
          dangerouslySetInnerHTML={{
            __html: `
              const theme = localStorage.getItem("theme");
              document.documentElement.setAttribute("data-theme", theme);
              console.log(theme);
            `,
          }}
        ></script>
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

export default Document;

 

리액트의 경우 해당 스크립트 코드를 public/index.html 파일에 심으면 됩니다.

 

 

새로고침 시 기존 모드 유지

 

 

 

반응형

+ Recent posts