其中最常见的要求的软件功能是暗模式(或夜间模式,因为别人称呼它)。我们每天使用的应用程序中都会看到黑暗模式。从移动应用程序到Web应用程序,暗模式对于想要照顾用户眼睛的公司而言至关重要。
深色模式是一项补充功能,可在UI中显示大部分深色表面。大多数主要公司(例如YouTube,Twitter和Netflix)已在其移动和网络应用程序中采用了暗模式。
虽然我们不会深入研究React和样式化组件,但是对React,CSS和样式化组件的基本知识将派上用场。本教程将使那些喜欢深色模式的人受益于那些希望增强其Web应用程序的人。
在撰写本文之前的几天,StackOverflow宣布发布了暗模式,使用户有机会在两种模式之间进行切换。
深色模式可减轻眼睛疲劳,并在长时间在计算机或手机上工作时提供帮助。
什么是黑暗模式?
深色模式是任何在深色背景上显示浅色文本和界面元素的界面的配色方案,这使屏幕更易于查看手机,平板电脑和计算机。暗模式减少了屏幕发出的光,同时保持了可读性所需的最小颜色对比度。
为什么要关心黑暗模式?
暗模式通过减少眼睛疲劳,将屏幕调整为当前的光照条件并在夜间或黑暗环境中提供易用性来增强视觉人体工程学。
在我们的应用中实施暗模式之前,让我们先看看它的好处。
节电
Web和移动应用程序中的暗模式可以延长设备的电池寿命。Google已经确认 OLED屏幕的暗模式对电池寿命有很大帮助。
例如,在亮度为50%的情况下,YouTube应用中的黑暗模式比纯白色背景可节省约15%的屏幕能量。屏幕亮度为100%时,深色界面可节省60%的屏幕能量。
暗模式很漂亮
暗模式很漂亮,它可以显着增强屏幕的吸引力。
尽管大多数产品都具有类似的淡淡白色外观,但深色模式却提供了不同的感觉和神秘感。
它还为以新颖的方式呈现图形内容(例如仪表板,图片和照片)提供了绝佳的机会。
既然您知道了为什么要在下一个Web应用程序中实现暗模式,那么让我们深入研究样式化组件,这是本教程的定义资源。
深色模式是任何在深色背景上显示浅色文本和界面元素的界面的配色方案,这使得在手机,平板电脑和计算机上查看起来更加容易。
“
什么是样式组件?
在本文中,我们将经常使用样式化的组件库。一直有很多样式来设计现代Web应用程序。在文档级别有一种传统的样式化方法,包括创建index.css
文件并将其链接到HTML或在HTML文件中进行样式化。
自从CSS-in-JS引入以来,Web应用程序的样式最近发生了很多变化。
CSS-in-JS是指使用JavaScript组成CSS的模式。它利用标记的模板文字来对JavaScript文件中的组件进行样式设置。
要了解有关CSS-in-JS的更多信息,请查看Anna Monus关于该主题的文章。
styled-components是一个CSS-in-JS库,可让您使用自己喜欢的CSS的所有功能,包括媒体查询,伪选择器和嵌套。
为什么使用样式组件?
创建样式组件的原因如下:
- 没有类名地狱
样式化的组件会为您的样式生成唯一的类名,而不是您费力地为元素查找类名。您永远不必担心拼写错误或使用没有意义的类名。 - 使用props
styled-components允许我们props
使用React中常用的参数来扩展样式属性,从而通过应用程序的状态动态影响组件的感觉。 - 支持Sass语法开箱即用即可
编写Sass语法,而无需设置任何预处理程序或使用样式组件即可使用其他构建工具。在样式定义中,可以使用该&
字符作为当前组件的目标,使用伪选择器,并尝试嵌套。 - 通过导出包装器组件,主题化
样式化组件具有完全的主题化支持ThemeProvider
。该组件通过Context API为自身内的所有React组件提供了主题。在渲染树中,所有样式化的组件都可以访问所提供的主题,即使它们位于多个级别。随着本教程的继续,我们将更深入地了解样式化组件的主题功能。
要了解样式化组件的更多优点,请查看Kris Guzman的文章。
实施黑暗模式
在本文中,我们将在类似YouTube的简单网页上实现暗模式。
要继续进行,请确保您从starter
branch克隆了原始存储库。
配置
让我们在package.json
文件中安装所有依赖项。在终端上,运行以下命令:
成功安装后,运行npm start
。这是未实现暗模式的网页外观。
要安装styled-components
,请在您的终端上运行npm install styled-components
。
实作
要实现暗模式,我们需要创建四个不同的组件。
Theme
这包含我们的浅色和深色主题的颜色属性。GlobalStyles
这包含整个文档的全局样式。Toggler
这包含用于切换功能的按钮元素。useDarkMode
这个自定义钩子处理主题更改和主题在localStorage中的持久性背后的逻辑。
主题组件
在src
文件夹中,您将在components
文件夹中看到组件。创建一个Themes.js
文件,并向其中添加以下代码。
在这里,我们定义和出口lightTheme
,并darkTheme
具有鲜明的颜色变量的对象。随时尝试和定制适合您的变量。
GLOBALSTYLES组件
保留在您的components
文件夹中,创建一个globalStyles.js
文件,并添加以下代码:
我们是createGlobalStyle
从样式组件中导入的。该createGlobalStyle
方法替换了样式组件版本3中现已弃用的injectGlobal方法。此方法生成一个React组件,将其添加到组件树后,会将全局样式注入到文档中(在我们的示例中为)App.js
。
我们定义了一个GlobalStyle
组件,background
并color
为主题对象的值分配了属性。因此,每次我们切换切换开关时,其值都会根据传递给ThemeProvider
它的深色主题或浅色主题对象而改变(稍后将继续进行创建)。
的transition属性0.50s
使此更改更平稳地发生,因此当我们来回切换时,我们可以看到更改的发生。
创建主题切换功能
要实现主题切换功能,我们只需要添加几行代码即可。在App.js
文件中,添加以下代码(请注意,突出显示的代码是您应该添加的代码):
高亮显示的代码是新添加到的代码App.js
。我们是ThemeProvider
从导入的styled-components
。ThemeProvider
是样式化组件库中提供主题支持的帮助程序组件。该帮助器组件通过Context API将主题注入到其自身下方的所有React组件中。
在渲染树中,所有样式化的组件都可以访问所提供的主题,即使它们位于多个级别。查看“ 主题 ”部分。
接下来,我们GlobalStyle
从中导入包装器./components/Globalstyle
。最后,从顶部,我们从中导入lightTheme
和darkTheme
对象./components/Themes
。
为了创建切换方法,我们需要一个保持主题初始颜色值的状态。因此,我们创建一个theme
状态,并light
使用useState
挂钩将初始状态设置为。
现在,切换功能。
该themeToggler
方法使用三元运算符检查的状态theme
,并根据条件的值切换暗或亮。
ThemeProvider
,一个样式化组件的帮助器组件,将所有内容包装在该return
语句中,并在其下方注入任何组件。请记住,我们GlobalStyles
将全局样式注入到我们的组件中;因此,它在ThemeProvider
包装器组件内部被调用。
最后,我们创建了一个带有onClick
事件的按钮,该事件将themeToggler
方法分配给它。
让我们看看到目前为止的结果。
我们的App.js
文件需要重构;它的很多代码不是DRY。(DRY代表“不要重复自己”,这是旨在减少重复的软件开发的基本原理。)所有逻辑似乎都存在于App.js
;为了清楚起见,最好将逻辑分开。因此,我们将创建一个处理切换功能的组件。
切换组件
仍在components
文件夹中,创建一个Toggler.js
文件,并向其中添加以下代码:
为了使内容整洁,我们Toggle
使用styled
样式化组件中的函数在组件中设置了切换按钮的样式。
这纯粹是为了演示;您可以根据需要设置按钮的样式。
在Toggle
组件内部,我们传递了两个道具:
- 在
theme
提供当前主题(亮或暗); - 该
toggleTheme
功能将用于在主题之间切换。
接下来,我们返回Button
组件并toggleTheme
为onClick
事件分配一个函数。
最后,我们propTypes
用来定义我们的类型,确保我们theme
是string
and isRequired
,而我们toggleTheme
是func
and isRequired
。
使用自定义挂钩(useDarkMode
)
在构建应用程序时,可伸缩性至关重要,这意味着我们的业务逻辑必须可重用,以便我们可以在很多地方甚至在不同的项目中使用它。
这就是为什么将切换功能移至单独的组件会很棒。为此,我们将创建自己的自定义钩子。
让我们useDarkMode.js
在components
文件夹中创建一个名为的新文件,然后进行一些调整,将逻辑移至该文件。将以下代码添加到文件中:
我们在这里添加了一些东西。
setMode
我们localStorage
过去常常在浏览器中的会话之间保持不变。因此,如果用户选择了深色或浅色主题,则这是他们下次访问应用程序或重新加载页面时所得到的。因此,此函数设置我们的状态并传递theme
给localStorage
。themeToggler
此函数使用三元运算符检查主题的状态,并根据条件的真实性切换暗或亮。useEffect
我们已经实现了useEffect
挂钩来检查组件的安装。如果用户以前选择了主题,我们会将其传递给我们的setTheme
功能。最后,我们将返回theme
,其中包含所选内容theme
和themeToggler
在模式之间切换的函数。
我想您会同意我们的暗模式组件看起来很时尚。
让我们继续App.js
进行最后的修饰。
高亮显示的代码新添加到中App.js
。
首先,我们导入自定义钩子,对theme
and themeToggler
道具进行解构,并使用useDarkMode
函数进行设置。
请注意,该useDarkMode
方法替换了我们theme
最初位于中的状态App.js
。
我们声明一个themeMode
变量,该变量根据当时的theme
模式情况呈现浅色或深色主题。
现在,我们的ThemeProvider
包装器组件将刚刚创建的themeMode
变量分配给theme
prop。
最后,我们传入常规Toggle
组件代替常规按钮。
记住,在我们的Toggle
组件中,我们定义并设置了按钮样式,并将两者theme
以及toggleTheme
它们作为道具传递给他们。因此,我们要做的就是将这些道具适当地传递给该Toggle
组件,该组件将充当我们中的按钮App.js
。
是! 设置了我们的黑暗模式,并且该模式持续存在,当刷新页面或在新标签页中访问页面时,颜色不变。
让我们看看实际结果:
几乎所有的东西都运行良好,但是我们可以做一件事来使我们的体验更加出色。切换到深色主题,然后重新加载页面。您看到按钮中的蓝色在灰色之前短暂加载了吗?发生这种情况是因为我们的useState
钩子light
最初启动了主题。之后,useEffect
运行,检查localStorage
,然后将设置theme
为dark
。让我们跳到我们的自定义钩子useDarkMode.js
并添加一些代码:
高亮显示的代码是唯一添加到的代码useDarkMode.js
。我们创建了另一个名为的状态mountedComponent
,并将默认值设置为false
使用useState
挂钩。接下来,在useEffect
挂钩中,将mountedComponent
状态设置为true
using setMountedComponent
。最后,在return
数组中,我们包含mountedComponent
状态。
最后,让我们添加一些代码App.js
以使其全部正常工作。
我们已经将mountedComponent
状态作为道具添加到了useDarkMode
钩子中,并且检查了组件是否已安装,因为这是useEffect
钩子中发生的事情。如果尚未发生,那么我们将渲染一个empty div
。
让我们看看暗模式网页的结果。
现在,您会注意到在暗模式下,当页面重新加载时,按钮的颜色不会改变。
结论
黑暗模式越来越成为用户的首选,ThemeProvider
在样式化组件中使用主题包装器时,在React Web应用程序中实现它要容易得多。在实现暗模式时,继续尝试样式化组件。您可以添加图标而不是按钮。
请确实在下面的评论部分中使用样式化组件中的主题功能分享您的反馈和经验。我很乐意看到您的想法!
GitHub上提供了本文的支持存储库。另外,在CodeSandbox上签出。