Javascript 使用情感实现全局主题化?

Javascript 使用情感实现全局主题化?,javascript,css,reactjs,styled-components,emotion,Javascript,Css,Reactjs,Styled Components,Emotion,我遵循了《情感》的作者Kye提到的解决方案,尽管我并不完全理解 因此,我制作了一个小程序来实现问题中提供的细节。如何使背景色主题在injectGlobal中工作?我找到了解决方案。完整的解决方案可在或中找到 制作一个包含应用程序主题的theme.js文件 theme.js 将全局组件包装在中,使用主题&它应该使用主题道具 Global.js 然后用Global组件包装你的App组件。由于全局组件需要主题它应该包装在主题提供程序中 index.js 从“React”导入React; 从“react

我遵循了《情感》的作者Kye提到的解决方案,尽管我并不完全理解


因此,我制作了一个小程序来实现问题中提供的细节。如何使
背景色
主题在
injectGlobal
中工作?

我找到了解决方案。完整的解决方案可在或中找到

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

theme.js 将
全局
组件包装在
中,使用主题
&它应该使用
主题
道具

Global.js 然后用
Global
组件包装你的
App
组件。由于
全局
组件需要
主题
它应该包装在
主题提供程序中

index.js
从“React”导入React;
从“react dom”导入react dom;
从“情感主题化”中导入{ThemeProvider};
从“/injectGlobal”导入全局;
从“/theme”导入{theme};
类应用程序扩展了React.Component{
状态={
小岛:是的,
标题:“轻主题”,
主题:theme.LIGHT
};
_切换主题=()=>{
const{isLight}=this.state;
const title=isLight?“黑暗主题”:“光明主题”;
const newTheme=isLight?theme.DARK:theme.LIGHT;
这是我的国家({
小岛:!小岛,
标题
主题:新主题
});
};
render(){
const{title,theme}=this.state;
返回(
{title}
切换主题
);
}
}
const rootElement=document.getElementById(“根”);
render(,rootElement);

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

为使用情感10的人更新:

从“React”导入React
从“情感主题化”导入{useTheme,ThemeProvider}
从“@emotion/core”导入{css,Global}
常量GlobalStyles=()=>{
const theme=useTheme()
返回(
)
}
常量应用=()=>(
你好
)
export const theme = {
  LIGHT: {
    textColor: "black",
    bgColor: "white"
  },
  DARK: {
    textColor: "white",
    bgColor: "black"
  }
};
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);
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);