使用React构建一个可切换的多色主题
前端开发人员面临的任务是制作一个能提高用户体验和适应用户喜好的用户界面。带有CSS的React.js主要可以用来创建一个多色切换的主题。
用户可以在特定的时间点,根据自己的喜好,在不同的主题颜色之间进行切换。
简介
在这篇文章中,我们将讨论用React.js、CSS和其他依赖性来建立一个多色主题的各种步骤和要求。
前提条件
读者应该有React.js、CSS和任何他们选择的设计库的经验。如果你对上述语言或框架不熟悉,在继续之前,请花点时间了解一下基础知识。
React.js中主题处理程序的组件
为了实现建立一个可切换的多色主题的目标,你的网络应用程序必须拥有以下组件。
- 颜色的上下文Api 状态管理
- 颜色选择器组件
- 导航条
- 侧边栏
- 饲料
- 页面元素的设计依赖性。
开始使用React.js进行主题开发
为了最大限度地加深理解,本教程将以程序的形式来组织。用react ,完成构建一个可切换的多色主题所需的各个步骤将被讨论如下。
第1步:创建React应用程序
每个react 开发的第一步是创建react 应用程序。这个步骤很容易实现。
要创建你的react 应用程序,在命令终端,运行如下所示的命令。
npx create-react-app Demo-app
或
Yarn create-react-app Demo-app
上面的command 片段将创建你的react 应用程序,安装默认的开发依赖项,最后提供一个模板来开始你的应用开发。
第2步:添加所需的应用程序依赖项
React.js通常能够做很多事情,但在它上面添加一些依赖项将提供一个强大的网络开发库,足以处理众多需求。
对于我们的项目,我们将安装以下依赖项。
"reactstrap": "8.7.1",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^2.0.3"
npm install
第3步:创建主题上下文
React中的状态管理可以通过两(2)种方式完成,即。
- React上下文API。
- React redux。
为了简单起见,我们将使用前者,即react context API。它将使我们能够对我们的主题组件进行实时监控。
为了设置我们的主题上下文,我们创建一个ThemeContext.js 文件。
然后,我们实现下面的代码片断。
import React, {createContext, useState } from "react";
const ThemeColors = {
primary: "brown",
blue: "blue",
red: "red",
purple: "purple",
orange: "orange",
green: "green"
};
const ThemeColorContext = createContext({
color: ThemeColors.blue,
changeColor: (color) => {},
});
export default function ThemeColorWrapper(props) {
const [color, setColor] = useState(ThemeColors.blue);
function changeColor(color) {
setColor(color);
}
return (
<ThemeColorContext.Provider
value={{ color: color, changeColor: changeColor }}
>
{props.children}
</ThemeColorContext.Provider>
);
}
我们创建了一个ThemeWrapper ,它将包裹我们所有的组件并向用户提供所需的主题颜色。
该代码块还创建了一个react-context ,容纳六(6)种颜色,这些颜色是。
- 棕色
- 蓝色
- 红色
- 紫色
- 橙色和
- 绿色
这些颜色最终将成为我们主题组件的一部分。
第4步:创建各种组件
我们的应用程序将有四(4)个组件,即:
- 主题切换器
- 导航栏
- 侧边栏
- 馈送
现在我们将继续创建我们想要的页面组件。
主题切换器组件
主题切换器组件将使用户能够与主题颜色互动。一组可用的颜色将显示在一个面板上,用户可以从中挑选,其他组件也可以立即适应。
为了实现这一目标,我们需要创建一个ThemeToggler.js 文件。
然后我们进行下面的代码片段。
import React from "react";
// importing the required reactstrap components
import { Dropdown, DropdownToggle, Badge } from "reactstrap";
import { ThemeColors } from "/ThemeColorContext";
function ThemeToggler(props) {
const [dropdownOpen, setdropdownOpen] = React.useState(false);
const handleClick = () => {
setdropdownOpen(!dropdownOpen);
};
return (
<div className="fixed-plugin">
<Dropdown isOpen={dropdownOpen} toggle={handleClick}>
<DropdownToggle tag="div">
<i className="fa fa-cog fa-2x" />
</DropdownToggle>
<ul className="dropdown-menu show">
<li className="header-title">SELECT THEME</li>
<li className="adjustments-line">
<div className="badge-colors text-center">
<Badge
color="primary"
className={
props.bgColor === ThemeColors.primary ? "active" : ""
}
onClick={() => {
props.handleTheme(ThemeColors.primary);
}}
/>{" "}
<Badge
color="info"
className={
props.bgColor === ThemeColors.blue ? "active" : ""
}
onClick={() => {
props.handleTheme(ThemeColors.blue);
}}
/>{" "}
<Badge
color="info"
className={
props.bgColor === ThemeColors.purple ? "active" : ""
}
onClick={() => {
props.handleTheme(ThemeColors.purple);
}}
/>{" "}
<Badge
color="info"
className={
props.bgColor === ThemeColors.orange ? "active" : ""
}
onClick={() => {
props.handleTheme(ThemeColors.orange);
}}
/>{" "}
<Badge
color="success"
className={
props.bgColor === ThemeColors.green ? "active" : ""
}
onClick={() => {
props.handleTheme(ThemeColors.green);
}}
/>{" "}
<Badge
color="success"
className={
props.bgColor === ThemeColors.red ? "active" : ""
}
onClick={() => {
props.handleTheme(ThemeColors.red);
}}
/>{" "}
</div>
</li>
</ul>
</Dropdown>
</div>
);
}
export default ThemeToggler;
我们已经成功地创建了一个ThemeToggler ,在一个颜色面板上有六种颜色明显的位移。

导航条组件
大多数现代网站通常有一个导航条,我们的网站也不会例外。导航条为用户提供了网站的简要介绍,同时也便于用户选择路线。
我们的Navbar 组件通过theme-context 的帮助将具有颜色切换能力,它将与其他组件相连。
要创建一个Navbar 组件,我们首先需要在src 文件夹中创建一个Navbar.js 文件,然后我们实现下面的代码片段。
import React from "react";
import classNames from "classnames";
// importing the required reactstrap components
import {
Button,
Collapse,
DropdownToggle,
DropdownMenu,
DropdownItem,
UncontrolledDropdown,
InputGroup,
NavbarBrand,
Navbar,
NavLink,
Nav,
Container,
NavbarToggler,
} from "reactstrap";
function Navbar(props) {
const [collapseOpen, setcollapseOpen] = React.useState(false);
const toggleCollapse = () => {
if (collapseOpen) {
setcolor("navbar-transparent");
} else {
setcolor("bg-white");
}
setcollapseOpen(!collapseOpen);
};
return (
< ThemeColorContext.Consumer>
{({ color }) => (
<Navbar className=navbar-absolute" expand="lg">
<Container fluid>
<div className="navbar-wrapper">
<div
className="navbar-toggle", {
toggled: props.sidebarOpened,
})}
>
<NavbarToggler>
<span className="navbar-toggler-bar bar1" />
<span className="navbar-toggler-bar bar2" />
<span className="navbar-toggler-bar bar3" />
</NavbarToggler>
</div>
<NavbarBrand onClick={(e) => e.preventDefault()}>
<div className="logo-img">
<img
style={{ width: "5%" }}
src="https://images.pexels.com/photos/2235130/pexels-photo-2235130.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
alt="logo image"
/>
Demo App
</div>
</NavbarBrand>
</div>
<NavbarToggler onClick={toggleCollapse}>
<span className="navbar-toggler-bar navbar-kebab" />
<span className="navbar-toggler-bar navbar-kebab" />
<span className="navbar-toggler-bar navbar-kebab" />
</NavbarToggler>
<Collapse navbar isOpen={collapseOpen}>
<Nav className="ml-auto" navbar>
<InputGroup className="search-bar">
<Button color="link" onClick={modalSearchToggle}>
<i className="tim-icons icon-zoom-split" />
<span className="d-lg-none d-md-block">Search</span>
</Button>
</InputGroup>
<UncontrolledDropdown nav>
<DropdownToggle
caret
color="default"
nav
onClick={(e) => e.preventDefault()}
>
<div className="photo">
<img
alt="..."
src="https://images.pexels.com/photos/168938/pexels-photo-168938.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
/>
</div>
<p className="lg-none" onClick={logout}>
Log out
</p>
</DropdownToggle>
<DropdownMenu className="dropdown-navbar" right tag="ul">
<NavLink tag="li">
<DropdownItem className="nav-item">Profile</DropdownItem>
</NavLink>
<NavLink tag="li">
<DropdownItem className="nav-item">Settings</DropdownItem>
</NavLink>
<DropdownItem divider tag="li" />
<NavLink tag="li">
<DropdownItem className="nav-item" onClick={logout}>
Log out
</DropdownItem>
</NavLink>
</DropdownMenu>
</UncontrolledDropdown>
<li className="separator lg-none" />
</Nav>
</Collapse>
</Container>
</Navbar>
)}
</ ThemeColorContext.Consumer>
);
}
export default Navbar;
从上面的代码片断中,我们从文章开头部分安装的reactstrap 依赖关系中导入了很多元素。
这些元素包括。
- 按钮
- 下拉式
- 折叠
- 容器
- 导航链接
- 导航栏切换器。等等。
我们还在我们的Navbar ,把各种元素放在适当的位置,等待造型。你可以根据你所需要的规格自由地定制它们。然后,我们创建了一个toggleCollapse 函数来处理在中小屏幕尺寸上切换Sidebar 。

侧边栏组件
侧边栏也是网站的一个重要部分,它在用户互动和应用内的路由中起着重要作用。
我们的侧边栏将被放置在Feeds 组件旁边,将包含图标、文本、标题和一些链接。
要创建一个Sidebar 组件,在你的src 文件夹中,创建一个Sidebar.js 文件,它将容纳下面的代码片段。
import React from "react";
import { PropTypes } from "prop-types";
import { Icon} from "semantic-ui-react";
// importing the reactstrap components
import { Nav } from "reactstrap";
import { ThemeColorContext } from "/ ThemeColorContext ";
function Sidebar() {
const sidebarRef = React.useRef(null);
const SidebarProps = ()=>{
return(
<div className=sidebar-props>
<Icon className="side-icon" name={iconName} size="large" />
<h2 style={{ paddingTop: "23px" }}>{title}</h2>
</div>
)
}
return (
< ThemeColorContext.Consumer>
{({ color }) => (
<div className="sidebar" data={color}>
<div className="sidebar-wrapper sidebar-container" ref={sidebarRef}>
<div className="logo">
<div className="logo-img">
<img
src="https://www.pexels.com/photo/white-and-blue-route-66-logo-1162361/"
alt="your logo"
/>
</div>
<h2 className="simple-text">Demo App</h2>
</div>
<Nav>
<SidebarProps iconName="home" title="Home" />
<SidebarProps iconName="globe" title="Explore" />
<SidebarProps iconName="bell" title="Notifications" />
<SidebarProps iconName="envelope" title="Messages" />
<SidebarProps iconName="bookmark" title="Bookmark" />
<SidebarProps iconName="user" title="Profile" />
</Nav>
</div>
</div>
)}
</ ThemeColorContext.Consumer>
);
}
export default Sidebar;
为了简化工作,我们创建了一个可重复使用的SidebarProps 组件,接受一个侧边栏图标和一个文本。
我们使用了以下semantic-ui-react 图标。
- 首页
- 探索
- 通知
- 留言
- 书签和
- 简介
这些图标为用户提供了我们应用程序中的路线和组件的清晰视图。
然后,我们用之前创建的ThemeColorContext ,将我们的整个Sidebar 组件包裹起来,以处理我们侧边栏的主题颜色。

馈送组件
在大多数情况下,feeds页面是在网站上可以找到文本、图片、图标、gif等网络内容。
我们将创建一个Feeds ,它将显示在已经创建的Sidebar 的右边。Feeds 将保持简单,只有几个元素,因为它不是本文的重点。你可以随意添加和定制你想要的元素。
在我们的src 文件夹中,我们创建了一个新的文件Feeds.js ,此后我们可以实现下面的代码片段。
import React, { useState } from "react";
import { Avatar, Button, Card, Image, Modal } from "semantic-ui-react";
export function Feeds() {
const [open, setOpen] = useState(false);
return (
<Card fluid className="post-card">
<Card.Content>
<div className="post-content">
<div className="user-details">
<Avatar src={profilePic} />
<div className="timestamp">
<div className="user-details">
<div className="display-name-badge">
<h3>Slim Mike</h3>
</div>
</div>
<Card.Meta className="post-time">35 mins ago</Card.Meta>
</div>
</div>
<Card.Description className="post-body">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure
facere fugiat, perferendis optio obcaecati tempora laboriosam,
provident expedita odio eius adipisci, corporis vel eligendi
deleniti excepturi blanditiis et omnis? Debitis.
</p>
</Card.Description>
</div>
<Modal
onClose={() => setOpen(false)}
onOpen={() => setOpen(true)}
open={open}
size="tiny"
trigger={
<Image
className="post-img"
floated="right"
size="large"
src="https://images.pexels.com/photos/1478442/pexels-photo-1478442.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
/>
}
>
<Modal.Content image>
<Image
size="massive"
src="https://images.pexels.com/photos/1478442/pexels-photo-1478442.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
wrapped
/>
</Modal.Content>
</Modal>
</Card.Content>
<Card.Content extra>
<Button
labelPosition="right"
as="div"
color="teal"
basic
content="Comment"
icon="comments"
label={{
basic: true,
color: "teal",
pointing: null,
content: 3,
}}
/>
</Card.Content>
</Card>
);
}
从上面的代码片断中,我们创建了一个类似于社交媒体新闻源的页面。
我们还从semantic-ui-react 中导入了以下元素。
- 头像
- 模态
- 卡片
- 图片
- 按钮
如果正确实现,你应该有一个原始的Feeds ,准备好进行造型和查看。

第5步:对各种组件进行造型
在上一步中,我们创建了一个Navbar 、Sidebar 和Feeds 组件。为了改善这些组件的外观和风格,我们必须添加所需的样式。
为了使我们的组件具有风格,我们创建了一个styles.css 文件,它将被用来定制我们的组件。
下面的代码片断应该被执行。
.navbar .navbar-wrapper {
display: flex;
align-items: center;
}
.navbar.navbar-absolute {
position: absolute;
z-index: 1050;
}
.navbar-toggler {
padding: 0.25rem 0.75rem;
font-size: 0.99925rem;
line-height: 1;
background-color: transparent;
border: 0.0625rem solid transparent;
border-radius: 0.25rem;
}
.search-bar {
margin-left: 30px;
}
.search-bar .btn {
margin: 0;
}
.logo-img {
max-width: 55px;
width: fit-content;
}
.search-bar.input-group {
border-radius: 25px;
z-index: 4;
margin-bottom: 0;
height: 43px;
padding-right: 5px;
}
/* Sidebar styles */
.sidebar .sidebar-wrapper {
width: 100%;
min-height: 100%;
max-height: calc(100vh - 705px);
z-index: 4;
position: relative;
overflow: auto;
}
.simple-text {
padding: 0.5rem 0;
white-space: nowrap;
color: #ffffff;
font-weight: 400;
}
.sidebar-props {
margin-top: 10px;
height: fit-content;
display: flex;
padding-bottom: 5px;
border: 1px solid #ccbcbc;
border-radius: 20px;
cursor: pointer;
color: #1a1919;
}
.sidebar-props .icon {
font-size: small !important;
}
.sidebar-props h2 {
font-size: medium;
font-weight: 600;
margin-right: 20px;
}
/* Main page styles */
.post-card {
margin: auto !important;
width: 100% !important;
background: #ecf3ff;
height: fit-content !important;
border-radius: 10px !important;
padding-top: 10px !important;
box-shadow: 0 5px 17px -7px rgba(0, 0, 0, 0.75) !important;
}
.user-details {
display: flex;
flex-direction: column;
margin-right: 5px;
}
.post-time {
padding-top: 4px;
}
.post-body {
color: black !important;
margin-left: 5%;
font-size: medium;
}
.post-img {
width: 100vw !important;
max-height: 85vh !important;
margin-left: 0 !important;
overflow: hidden;
}
.timestamp {
display: flex;
}
我们已经成功地用上面的代码片断为我们的组件设计了样式。上面的CSS代码段为所有三个组件提供了许多样式。
我们通过针对分配给每个元素的className ,实现了这一点。
第6步:显示组件
在前面的步骤中,我们创建了ThemeToggler、Navbar、Sidebar和Feeds组件,并对其进行了样式设计。
我们将继续在App 中显示我们的组件,然后启动我们的开发服务器,在浏览器中查看我们的Multi-Color Theme 。
要做到这一点,在我们的App.js 文件中,我们需要导入我们的组件,如下所示。
import React from "react";
// our components
import Navbar from "/Navbar.js";
import "/styles.css";
import Sidebar from "/Sidebar.js";
import ThemeTogler from "/ThemeTogler.js";
import { ThemeColorContext } from "/ThemeColorContext";
function App() {
return (
<ThemeColorContext.Consumer>
{({ color, changeColor }) => (
<React.Fragment>
<div className="wrapper">
<div className="main-panel" data={color}>
<Navbar />
</div>
<Sidebar />
</div>
<ThemeTogler bgColor={color} handleBgClick={changeColor} />
</React.Fragment>
)}
</ThemeColorContext.Consumer>
);
}
export default App;
一旦上面的代码片断被正确实现,应用程序组件看起来就可以查看了。
要在浏览器上查看我们的应用程序,请打开你的command terminal ,运行以下命令。
Npm:
npm start
或者对于yarn用户。
yarn start

一旦开发服务器启动,你应该能够在浏览器上查看该应用程序。
总结
在这篇文章中,我们应用了各种概念,用React.js创建一个多色主题。我们还研究了使用react-context-api 的状态管理。
本文涉及的概念可以在未来涉及颜色和主题管理的项目中使用。
我希望你发现这些内容对你的编程工作有帮助。