React学习与探索之路 (三) - Dark Mode with Styled Components
Closed this issue · 0 comments
citrus327 commented
React学习与探索之路 (三) - Dark Mode with Styled Components
一点想法
看到 Styled Components 文档里的一些高级特性,其中有一项是ThemeProvider,便萌生出使用他完成类似之前IOS上Night Shift的功能,也就是Dark Mode.
实现
放置ThemeProvider
Dark Mode影响的范围应该涉及 Login 页面以及 Dashboard. 所以ThemeProvider应该在这2个组件之上。
<ThemeProvider theme={this.state.theme}>
{
isAuthenticated ? <Login/> : <Dashboard/>
}
</ThemeProvider>
theme对象目前会有一个dark的Boolean属性对Dark Mode进行控制,UI层面上会提供一个Switch来进行模式的切换
Dark Mode的状态管理
this.state.theme = {
dark: false
}
// 定义handleDarkModeChange函数
handleDarkModeChange () {
this.setState((prev) => {
return {
theme: {
dark: !prev.theme.dark
}
}
})
}
render () {
return (
// 传入子组件
<ThemeProvider theme={this.state.theme}>
{
isAuthenticated ?
<Login handleDarkModeChange={this.handleDarkModeChange}/> :
<Dashboard handleDarkModeChange={this.handleDarkModeChange}/>
}
</ThemeProvider>
)
}
Dark Mode 的 CSS 实现
在样式方面,使用Styled Component的传参功能对样式进行修改
const StyledDashboardRoot = styled(StyledDiv)`
color: ${props => props.theme.dark ? 'white' : 'black'};
background-color: ${props => props.theme.dark ? '#f7f7f7' : '#282c34'};
transition: background-color 200ms linear, color 200ms linear;
...略
.MuiListItemIcon-root {
color: ${props => props.theme.dark ? 'white' : 'black'};
}
.MuiListSubheader-root {
color: ${props => props.theme.dark ? 'white' : 'black'};
opacity: 0.8;
}
.MuiDivider-root {
background-color: ${props => props.theme.dark ? '#f7f7f7' : undefined};
opacity: ${props => props.theme.dark ? '0.1' : undefined};
}
.dashboard-main {
background-color: ${props => props.theme.dark ? '#282c34' : '#f7f7f7'};
height: 100%;
...略
}
`
大致的实现就是黑暗模式下,背景色为暗色,主色调为亮色。�
使用Switch组件控制Dark Mode
<Switch
checked={this.props.theme.dark}
onChange={(event) => this.props.handleDarkModeChange(event.target.value)}
color="default"
size="small"
/>
可以看到这里的theme是从this.props里读取的,那也就是theme对象需要注入到组件级别,这里可以使用Styled-Components库提供的withTheme的高阶组件
withTheme(Navbar)
以上涉及了Provider的概念,具体Styled Components的传参功能,ThemeProvider和withTheme HOC的运用。