更改元素

时间:2016-11-22 16:00:52

标签: reactjs material-ui

我是React的新手,所以这可能很简单,但我不能为我的生活在文档中找到任何东西,因为该元素在ReactDOM之外。

我使用material-ui作为用户界面,它提供了两个主题:lightBaseTheme(默认)和darkBaseTheme颜色较深的主题。日夜两种模式。问题是既没有对<body>应用任何样式,所以页面背景不遵循主题。黑暗主题使用白色文本,默认白色背景上不显示。

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

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

我或许应该补充一点,最终的目的是能够即时更改主题,因此直接造型<body元素不是一种选择。

3 个答案:

答案 0 :(得分:4)

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

然而,你现在所做的工作是因为componentDidUpdate()在初始化时没有被调用,而你似乎没有用props / state更新它负荷。

  更新发生后立即调用

componentDidUpdate()。初始渲染不会调用此方法。 (React Docs

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

  装载组件后立即调用

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

Here's a good write up on the component lifecycle

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以在“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>
        );
    }
};