我是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
元素不是一种选择。
答案 0 :(得分:4)
如果可能,最好的解决方案是在你的React应用程序中使用顶级div
以及样式道具来解决你的问题。
然而,你现在所做的工作是因为componentDidUpdate()
在初始化时没有被调用,而你似乎没有用props / state更新它负荷。
更新发生后立即调用componentDidUpdate()。初始渲染不会调用此方法。 (React Docs)
相反,使用componentDidMount()
,一旦组件安装到您的DOM,就会调用它。
装载组件后立即调用componentDidMount()。需要DOM节点的初始化应该放在这里。如果需要从远程端点加载数据,这是实例化网络请求的好地方。在此方法中设置状态将触发重新渲染。 (React Docs)
答案 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>
);
}
};