更改 <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)
您可以使用 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>
);
}
};
我是 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)
您可以使用 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>
);
}
};