【问题标题】:Changing style on <body> element更改 <body> 元素的样式
【发布时间】:2017-04-06 09:31:54
【问题描述】:

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

我使用 material-ui 作为用户界面,它提供了两个主题:lightBaseTheme(默认)和颜色较深的darkBaseTheme。白天和晚上的模式。问题是既没有对&lt;body&gt; 应用任何样式,所以页面背景不符合主题。深色主题使用不会显示在默认白色背景上的白色文本。

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

但是怎么做呢?我尝试将代码放在顶级组件的 componentDidUpdate 方法中,但这似乎总是返回浅色主题。在任何情况下,我都不确定直接写入 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 的调用始终返回 lightBaseTheme,即使它已在渲染调用中设置。

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

【问题讨论】:

  • 是否会设计一些 div 包装整个应用程序,而不是 body 来满足您的需求?这样你就可以使用标准的style 道具。
  • @MichałWerner 嗨,我认为这并不理想,因为有时 react 会直接在正文上写入 html 元素,在 #root 之外。弹出框、对话框...

标签: reactjs material-ui


【解决方案1】:

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

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

componentDidUpdate() 在更新发生后立即调用。初始渲染不调用此方法。 (React Docs)

改为使用componentDidMount(),它会在组件安装到您的 DOM 后立即调用。

componentDidMount() 在组件安装后立即调用。需要 DOM 节点的初始化应该放在这里。如果您需要从远程端点加载数据,这是实例化网络请求的好地方。在此方法中设置状态将触发重新渲染。 (React Docs)

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

【讨论】:

  • React 应用程序中的顶级 DIV 是我的第一种方法,但我无法将它呈现在整个页面上。然而,这引发了另一个问题,作为一个不同的问题可能会更好。
  • 我选择了componentDidUpdate,因为如果主题改变了,我需要它来更新。即使有这个限制,即使使用深色主题,getMuiTheme 也会返回浅色主题。
  • 顶级 DIV 是我最终解决它的方法。我在 html 元素上设置了 min-height 并将其更改为 height: 100% 填充页面。不知道它会在以后导致问题,但如果它溢出页面。但现在我可以设置我想要的背景样式。
  • 这可能不适用于所有情况,因为 React MUI 可能会直接在主体上附加内容(如弹出框、选择、对话框...),而您的某些 div 样式不会针对这些内容
【解决方案2】:

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

【讨论】:

  • 我不确定这是否能让我即时更改样式。如果这不是一个要求,这似乎是一个理想的解决方案。
【解决方案3】:

您可以在“ref”回调期间捕获主题并将其分配给变量。然后在 componentDidMount() 中选择该变量(只调用一次,而 componentDidUpdate() 在任何时候 props 和 state 改变时都会被调用):

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

【讨论】:

    猜你喜欢
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2018-09-20
    • 2016-05-18
    相关资源
    最近更新 更多