嗨,这是我在Habr上的第一篇文章。 希望您对此感兴趣。
因此,我想开始一系列与ui-kit的创建直接或间接相关的帖子。

这篇文章的目的:找到一种解决方案来控制其组件在
React.js
中实现的应用程序的主题。 我们将使用两个全局主题-
黑暗与
光明 。
在此示例中,我将使用
create-react-context
模块创建上下文。
我们首先在项目的根目录(
src / )中创建一个名为
theme-context的文件夹。 该文件夹的结构如下所示:
theme-context/ ThemeConsumer/ ThemeConsumer.js index.js ThemeProvider/ ThemeProvider.js index.js constants.js context.js index.js
就个人而言,我总是从
index.js文件开始。 您从一开始就进行所有进出口,然后您的头就不会受到伤害。
主题上下文/ index.js export { ThemeProvider } from './ThemeProvider'; export { ThemeConsumer } from './ThemeConsumer';
主题上下文/ ThemeConsumer / index.js export { ThemeConsumer } from './ThemeConsumer';
主题上下文/ ThemeProvider / index.js export { ThemeProvider } from './ThemeProvider';
主题上下文/context.js接下来,我们将使用
来自此处的模块
,使用
createContext
(双关语很抱歉)创建上下文。
import createContext from 'create-react-context'; const { Provider, Consumer } = createContext(); export { Provider, Consumer };
导入
createContext
,将其销毁为
Provider
和
Consumer
,然后将其导出。
主题上下文/constants.js这里的一切都很简单,我们创建变量以免污染主文件。
export const themeLight = 'light'; export const themeDark = 'dark'; export const defaultTheme = themeLight; export const themes = [themeLight, themeDark];
正如我之前所说,我们的应用程序将具有两个主题-浅色和深色。
主题上下文/ ThemeProvider / ThemeProvider.js在这里,我们将讨论提供程序-每个
React.Context
对象中可用的组件。 它允许消费者聆听并响应不断变化的环境。
在我们的示例中,
道具是一个
theme
,将传递给该
Provider
的所有
流。
import React from 'react'; import { Provider } from '../context'; import { defaultTheme, themes } from '../constants'; function ThemeProvider({ theme, children }) { return <Provider value={theme}>{children}</Provider>; } export { ThemeProvider };
主题上下文/ ThemeConsumer / ThemeConsumer.js在此文件中,我们将与Consumer合作-这是一个“侦听,等待”上下文更改的组件。 该组件的子级是一个函数。 使用
Consumer
时这是必须的。
该函数接收当前上下文的值,并返回一个
React Node
,换句话说,一个组件。
在文档中:参数的值(在我们的示例中为{theme => / *以根据上下文值* /}进行可视化显示)将等于此上下文的
Provider
树中最接近的父级的props
theme
。
import React from 'react'; import { defaultTo } from 'lodash'; import { Consumer } from '../context'; import { defaultTheme, themes } from '../constants'; function ThemeConsumer(props) { return <Consumer>{theme => props.children(defaultTo(theme, props.defaultTheme))}</Consumer>; } export { ThemeConsumer };
这里值得注意以下几点:
如果未明确选择主题,则需要自动选择组件主题,为此,我使用
lodash
-
defaultTo
的
lodash
。 但是,可以通过许多其他方式来实现此功能。
就这样,主题上下文就可以使用了!
让我们看看如何应用它。 让我们创建一个简单的组件,该组件将侦听并响应应用程序的上下文。
.my-class { font-family: sans-serif; text-align: center; font-size: 30px; } .my-class-light { color: #39cccc; } .my-class-dark { color: #001a33; }
import React from "react"; import ReactDOM from "react-dom"; import cx from "classnames"; import { ThemeConsumer, ThemeProvider } from "./theme-context"; import "./styles.css"; function MyComponent() { const renderMyComponent = theme => { const myComponentClassName = cx("my-class", { "my-class-dark": theme === "dark", "my-class-light": theme === "light" }); return ( <div className={myComponentClassName}> <h1> </h1> </div> ); }; return <ThemeConsumer>{theme => renderMyComponent(theme)}</ThemeConsumer>; }; function App() { return ( <MyComponent /> ); } const rootElement = document.getElementById("root"); ReactDOM.render( // theme dark <ThemeProvider theme="light"> <App /> </ThemeProvider> , rootElement);
因此,我们将
<App />
包装在提供程序中,现在该主题已可供我们应用程序中的所有组件消费者使用。 接下来,
<App />
返回
<MyComponent />
,这是
,它将创建我们的组件并将其传递给我们应用程序的主题。 并且已经有一个主题作为参数:
<ThemeConsumer>{theme => renderMyComponent(theme)}</ThemeConsumer>
我们可以在创建组件时使用它
const renderMyComponent = theme => {
工作代码可以在这里找到 。
就这样,我希望您对这篇文章有用。 在下一篇文章中,我将尝试创建一个
媒体上下文 ,其功能将帮助我们可视化用户设备设备上的组件。
谢谢啦