更改 <body> 元素的样式

Changing style on <body> element

我是 React 的新手,所以这可能很简单,但我无法在文档中找到任何内容,因为元素在 React 之外DOM。

我正在为用户界面使用 material-ui,它提供了两个主题:lightBaseTheme(默认)和颜色较深的 darkBaseTheme。一种白天和黑夜模式。问题是没有对 <body> 应用任何样式,因此页面背景不符合主题。深色主题使用白色文本,不会在默认的白色背景上显示。

我怀疑我需要找到一个程序化的解决方案,并根据当前加载的主题设置背景颜色。

但是怎么办?我已经尝试将代码放在顶级组件的 componentDidUpdate 方法中,但这似乎总是 return 浅色主题。在任何情况下,我不确定直接写入 DOM 是好的做法,即使 body 元素在任何将受到 React 影响的东西之外。

export default class app extends React.Component {

    componentDidUpdate () {
        const muiTheme = getMuiTheme();
        const canvasColor = muiTheme.palette.canvasColor;
        document.body.style.backgroundColor = canvasColor;
    }

    render () {
        const muiTheme = getMuiTheme();
        return (
            <MuiThemeProvider muiTheme={getMuiTheme(darkBaseTheme)}>
                <span>Rest of the app goes here</span>
            </MuiThemeProvider>
        );
    }
};

componentDidUpdate 中对 getMuiTheme 的调用总是 returns lightBaseTheme,即使它已在渲染调用中设置。

我或许应该补充一点,最终目的是能够即时更改主题,因此不能直接设置 <body 元素的样式。

如果可能,最好的解决方案是在 React 应用程序中使用顶级 div 除了样式道具来解决您的问题。

但是,您现在拥有的将不起作用,因为 componentDidUpdate() 不会在初始化时被调用,并且您似乎没有在加载后使用 props/state 更新它。

componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render. (React Docs)

相反,请使用 componentDidMount(),一旦组件安装到您的 DOM,它就会被调用。

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. Setting state in this method will trigger a re-rendering. (React Docs)

Here's a good write up on the component lifecycle.

您可以使用 document.body.className。查看 w3schools。而 componentDidMount 是一个更好的地方。

您可以在 "ref" 回调期间捕获主题并将其分配给变量。然后在 componentDidMount() 中选择该变量(只调用一次,而 componentDidUpdate() 在道具和状态更改时调用):

export default class app extends React.Component {

    componentDidMount() {
        const canvasColor = this.theme.palette.canvasColor;
        document.body.style.backgroundColor = canvasColor;
    }

    render () {
        const muiTheme = getMuiTheme();
        return (
            <MuiThemeProvider ref={ref => (this.theme = ref.props.muiTheme)} muiTheme={getMuiTheme(darkBaseTheme)}>
                <span>Rest of the app goes here</span>
            </MuiThemeProvider>
        );
    }
};