【问题标题】:Enable Global Theming with Emotion?用情感启用全球主题?
【发布时间】:2019-01-09 07:12:33
【问题描述】:

我关注了https://github.com/emotion-js/emotion/issues/546,其中 Emotion 的作者 Kye 提到了一个解决方案,尽管我并不完全理解。

所以我做了一个小的CodeSandBox 来实现问题中提供的细节。如何使background-color 主题在injectGlobal 中工作?

【问题讨论】:

    标签: javascript css reactjs styled-components emotion


    【解决方案1】:

    我找到了解决方案。完整的解决方案可以在https://codesandbox.io/s/r76p996zymhttps://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 属性

    Global.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);
    

    然后用Global 组件包装您的App 组件。由于Global 组件需要theme,它应该被包裹在ThemeProvider

    index.js

    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);
    

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

    【讨论】:

      【解决方案2】:

      使用情感 10 的人的更新:

      import React from 'react'
      import { useTheme, ThemeProvider } from 'emotion-theming'
      import { css, Global } from '@emotion/core'
      
      const GlobalStyles = () => {
        const theme = useTheme()
        return (
          <Global styles={css`
            body {
              background: ${theme.bg};
            }
          `} />
        )
      }
      
      
      const App = () => (
        <ThemeProvider theme={{ bg: 'tomato' }}>
          <main>
            <h1>Hi</h1>
            <GlobalStyles />
          </main>
        </ThemeProvider>
      )
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-06
        • 2022-09-30
        • 2020-06-19
        • 1970-01-01
        • 2022-08-08
        • 2016-04-12
        • 1970-01-01
        • 2011-08-01
        相关资源
        最近更新 更多