代码之家  ›  专栏  ›  技术社区  ›  deadcoder0904

用情感实现全球主题化?

  •  2
  • deadcoder0904  · 技术社区  · 6 年前

    我已经跟随 https://github.com/emotion-js/emotion/issues/546 在《情感》一书中,作者凯尔提到了一个解决方案,尽管我并不完全理解它。

    所以我做了一个小 CodeSandBox 实现了问题中提供的详细信息。我该怎么做 background-color 主题作品 injectGlobal ?

    1 回复  |  直到 6 年前
        1
  •  1
  •   deadcoder0904    6 年前

    我找到了解决办法。完整的解决方案可在 https://codesandbox.io/s/r76p996zym https://github.com/deadcoder0904/emotion-global-theming

    做一个 theme.js 包含应用程序主题的文件

    主题JS

    export const theme = {
      LIGHT: {
        textColor: "black",
        bgColor: "white"
      },
      DARK: {
        textColor: "white",
        bgColor: "black"
      }
    };
    

    包裹 Global 组件在 withTheme &需要 theme 支柱

    全局的JS

    import React from "react";
    import { injectGlobal } from "react-emotion";
    import { withTheme } from "emotion-theming";
    
    class Global extends React.Component {
      componentDidUpdate(prevProps) {
        if (this.props.theme.bgColor !== prevProps.theme.bgColor) {
          window.document.body.style.backgroundColor = this.props.theme.bgColor;
        }
        if (this.props.theme.textColor !== prevProps.theme.textColor) {
          window.document.body.style.color = this.props.theme.textColor;
        }
      }
    
      render() {
        injectGlobal`
          color: ${this.props.theme.textColor};
          background-color: ${this.props.theme.bgColor};
        `;
        return React.Children.only(this.props.children);
      }
    }
    
    export default withTheme(Global);
    

    然后把你的 App 组件与 全球的 组件。AS 全球的 组件需要 主题 应该包在里面 ThemeProvider

    索引文件

    import React from "react";
    import ReactDOM from "react-dom";
    import { ThemeProvider } from "emotion-theming";
    
    import Global from "./injectGlobal";
    import { theme } from "./theme";
    
    class App extends React.Component {
      state = {
        isLight: true,
        title: "Light Theme",
        theme: theme.LIGHT
      };
    
      _toggleTheme = () => {
        const { isLight } = this.state;
        const title = isLight ? "Dark Theme" : "Light Theme";
        const newTheme = isLight ? theme.DARK : theme.LIGHT;
        this.setState({
          isLight: !isLight,
          title,
          theme: newTheme
        });
      };
    
      render() {
        const { title, theme } = this.state;
        return (
          <ThemeProvider theme={theme}>
            <Global>
              <React.Fragment>
                <h1>{title}</h1>
                <button onClick={this._toggleTheme}>Toggle Theme</button>
              </React.Fragment>
            </Global>
          </ThemeProvider>
        );
      }
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    注意-此答案仅在情感10发布和API更改之前有效。如果情感版本小于10,则使用此解决方案。