부트스트랩 테마 React 컨텍스트 제공자. 라이트 앤 다크 모드. webpack을 사용하여 CSS 파일을 동적으로 가져오고 가져오지 않습니다.

15058 단어 bootstrapwebpackreact
당신이 여기 있다면 아마도 당신의 앱에 Light/Dark 모드를 적용하기 위해 React 애플리케이션 주위에 Theme Provider를 만들려고 할 것입니다. 그러나 Bootstrap은 현재 사용 중인 제품의 CSS 솔루션입니다.

이를 달성하는 방법은 2개의 css 파일이 필요하며 각 파일은 각 테마 색상을 제공하고 하나는 dark 모드를 제공하고 다른 하나는 light 모드를 제공합니다. 일반적으로 부트스트랩 css 파일을 사용하여 수정하거나 인터넷에서 일부 테마를 구입하여 2개의 css 파일을 제공하지만 실제로 이 프로세스는 2개의 css 파일을 만들고 내부에 자신의 스타일을 넣어도 수행할 수 있습니다. 그런 다음 간단한 React 컨텍스트 공급자를 수행하는 ThemeProvider를 만들고 CSS 파일로 가져오기를 조정하고 토글합니다.

이렇게 하기 위해 가장 먼저 떠오르는 것은 반응 게으름과 서스펜스를 사용하는 것입니다. 이렇게 하면 필요할 때 두 파일을 모두 게으르게 가져올 수 있습니다. 이 방법의 문제점은 한 번만 작동한다는 것입니다. 먼저 첫 번째 CSS 파일을 가져온 다음 처음 전환할 때 두 번째 파일을 가져오지만 첫 번째 가져오기를 제거하지는 않습니다. React 재렌더링은 그렇게 하지 않기 때문입니다.

실제로 필요한 것은 가져오기를 전환하고 먼저 그 중 하나를 가져온 다음 두 번째 것을 가져올 때 첫 번째 것을 가져오기를 취소해야 합니다. 이를 위해서는 lazyStyleTag라는 Webpack 기능을 사용해야 합니다. 이 기능을 사용하면 스타일을 가져오고 지연 바인딩할 수 있습니다. 그래서 기본적으로 우리는 그것들을 묶고 우리가 원할 때 언제든지 묶을 수 있습니다.

먼저 webpacklazyStyleTag을 추가해 보겠습니다.

webpack 구성 파일로 이동하여 다음 규칙을 추가하십시오.

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        // Probly you already have this rule, add this line
        exclude: /\.lazy\.css$/i,
        use: ["style-loader", "css-loader"],
      },
      // And add this rule
      {
        test: /\.lazy\.css$/i,
        use: [
          { loader: "style-loader", options: { injectType: "lazyStyleTag" } },
          "css-loader",
        ],
      },
    ],
  },
};


이제 CSS 파일을 가져 와서 해당 설명서에 따라 이름을 lazy 명명 규칙으로 변경하십시오.

당신은 아마 이것을 가지고

light.css
dark.css 
// or
light.min.css
dark.min.css


이제 다음과 같습니다.

light.lazy.css
dark.lazy.css


그런 다음 간단한 React 컨텍스트에서 React Theme Provider를 생성합니다. 이 컨텍스트는 애플리케이션을 래핑하므로 컨텍스트 상태가 변경될 때마다 각 CSS 파일을 조건부로 바인딩 및 바인딩 해제합니다. 이 컨텍스트 상태는 동일한 파일에서 내보낼 사용자 정의 후크를 통해 setter뿐만 아니라 앱 내부 어디에서나 사용할 수 있습니다. 다음을 확인하십시오.

저는 TypeScript를 사용하고 있습니다만, 그럴 필요는 없습니다...

import React, {
    useEffect, createContext, useState, useContext,
} from 'react';
import { Nullable } from 'types';

// Now import both of your CSS files here like this:

// Import of CSS file number 1
import LightMode from './light.lazy.css';
// Import of CSS file number 2
import DarkMode from './dark.lazy.css';

// Typescript context interface, you don't need this if not // using TS
interface IContext {
    theme: Nullable<string>
    toggleTheme: () => void
}

const Context = createContext<IContext>({
    theme: null,
    toggleTheme: () => { },
});

// Your Provider component that returns 
// the Context.Provider
// Let's also play with the sessionStorage, 
// so this state doesn't
// brake with browser refresh or logouts
const ThemeProvider: React.FC = ({ children }) => {
    // Im initialazing here the state with any existing value in the 
    //sessionStorage, or not...
    const [theme, setTheme] = useState<Nullable<string>>(sessionStorage.getItem('themeMode') || 'dark');

    // this setter Fn we can pass down to anywhere
    const toggleTheme = () => {
        const newThemeValue = theme === 'dark' ? 'light' : 'dark';
        setTheme(newThemeValue);
        sessionStorage.setItem('themeMode', newThemeValue);
    };

    // Now the magic, this lazy css files you can use or unuse
    // This is exactly what you need, import the CSS but also unimport
    // the one you had imported before. An actual toggle of import in a 
    // dynamic way.. brought to you by webpack
    useEffect(() => {
        if (theme === 'light') {
            DarkMode.unuse();
            LightMode.use();
        } else if (theme == 'dark') {
            LightMode.unuse();
            DarkMode.use();
        }
    }, [theme]);


    return (
        <Context.Provider value={{ theme, toggleTheme }}>
            {children}
        </Context.Provider>
    );
};

export default ThemeProvider;
// This useTheme hook will give you the context anywhere to set the state of // theme and this will toggle the styles imported
export const useTheme = () => useContext(Context);


이 예에서와 같이 이 상태를 sessionStorage에 두어 사용자가 페이지를 다시 방문하거나 새로고침할 때마다 상태를 사용할 수 있도록 해야 합니다.

공급자에서 앱을 래핑합니다.

import ThemeProvider from './ThemeProvider'

const App = () => {
   return (
     <ThemeProvider>
        <App />
     <ThemeProvider/>
   )
}


이제 멋진useTheme 후크를 사용하여 응용 프로그램의 CSS 가져오기를 전환하기만 하면 됩니다.

import { useTheme } from './yourContextFile';


// inside your component
const AnyComponentDownTheTree = () => {

   const { theme, toggleTheme } = useTheme()

   // use the toggleTheme function to toggle 
   // and the theme actual value 
   // for your components, you might need 
   // disable something or set active a 
   // switch, etc, etc 

}

좋은 웹페이지 즐겨찾기