안녕하세요

styled-component 다크모드: "css variable"로 구현하자 themeProvider 대신에 본문

데이터시각화-KMG/Styled-Component

styled-component 다크모드: "css variable"로 구현하자 themeProvider 대신에

sakuraop 2023. 7. 9. 16:58

발단: 스타일드 컴포넌트로 다크모드 구현을 하는 방법을 검색해보면 themeProvider로 구현을 한다.

문제: 하지만 이 방식은 페이지를 리렌더링 하기 때문에 느리다.

Changing CSS Variables (e.g. changing themes) is significantly more performant, it doesn’t require React to re-render your entire app (or re-render almost anything in fact) and the changes will be instant. This is why frameworks like Emotion have experiments to use CSS Variables.

(100% 리렌더링이 일어나는 지에 대해서는 확실하지 않으나 사실상 모든 컴포넌트에 대해서 리렌더링이 일어났다.)


해결법: themeProvider를 버리고 css variable로 구현한다.

스타일드 컴포넌트의 createGlobalStyle로 생성한 css의 body에 테마를 지정한다.

=> (모르면 createGlobalStyle 검색)

const GlobalStyle = createGlobalStyle`

body[data-theme='light'] {
  --mainBlue: #2da0fa;
  --mainWhite: #ffffff;
}

body[data-theme='dark'] {
  --mainBlue: #0d92ff;
  --mainWhite: #2b2b2b;
}

`;

App의 상위컴포넌트에 GlobalStyle 컴포넌트를 위치시키면 테마를 프로젝트 전체에 적용시킬 수 있게 된다.

function App() {
  return (
    <>
      <GlobalStyle />
      <Wrapper>
        <FloatingMenu />
        <Navigation />
      </Wrapper>
    </>
  );
}

 

스타일 전환 버튼을 구현한다.

const NavHead: React.FC<NavHeadProps> = ({ ...navHeadProps }) => {
  const handleClickDarkModeButton = () => {
    if (debounceTimeoutRef.current === null) {
      setTheme(switchTheme);
      debounceTimeoutRef.current = window.setTimeout(() => {
        debounceTimeoutRef.current = null;
      }, 300);
    }
  };

  return (
    <NavHeadContainer>
      <DarkModeButton isDarkMode={isDarkMode} handleClickDarkModeButton={handleClickDarkModeButton} />
    </NavHeadContainer>
  );
};

=> UX를 위해 debounce를 300ms 주어서 연속된 클릭을 막도록 한다.

 


참고한 사이트

https://dominictobias.medium.com/is-it-time-to-ditch-your-react-themeprovider-e8560dad2652

 

Is it time to ditch your React ThemeProvider?

JS-in-CSS is now common practice, and your framework of choice probably provides a means to theme with JS Objects and a Provider. I’m…

dominictobias.medium.com

https://frontdev.tistory.com/entry/%EB%8B%A4%ED%81%AC%EB%AA%A8%EB%93%9C%EB%A5%BC-%EC%9C%84%ED%95%B4%EC%84%9C-Context-API%EB%B3%B4%EB%8B%A4-CSS-%EB%B3%80%EC%88%98%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%84%B8%EC%9A%94

 

다크모드를 위해서 Context API보다 CSS 변수를 활용하세요

다크모드를 관리할 때 일반적으로 Context API를 통해서 전체 테마를 바꾸는 ThemeProvider 기법을 많이 사용하게 됩니다. 여전히 CSS-in-JS는 최근 몇 년동안 CSS 사양이 많이 발전하고 개선되고, 최신 브

frontdev.tistory.com

https://www.sungikchoi.com/blog/detailed-dark-mode/

 

디테일 높은 다크모드 구현하기

다크모드를 구현하면서 얻게 된 팁들을 공유합니다.

www.sungikchoi.com