在React中使用Context API创建响应式应用程序设计

嗨,本文是本文的延续,在这里我决定开始一系列有关创建UI-Kit的小教程。 它描述了如何使用上下文创建应用程序主题。 今天,我想用另一个上下文来补充应用程序,这将帮助我们根据用户的设备显示UI的组件。

图片

在此示例中,我还将使用create-react-context模块。

任务树将与上一个相同。 让我们命名新的media-context文件夹。

 media-context/ MediaConsumer/ MediaConsumer.js index.js MediaProvider/ MediaProvider.js index.js constants.js context.js index.js 

我们将快速处理索引

媒体上下文/ index.js
 export { MediaProvider } from './MediaProvider'; export { MediaConsumer } from './MediaConsumer'; 

主题上下文/ MediaConsumer / index.js
 export { MediaConsumer } from './MediaConsumer'; 

主题上下文/ MediaProvider / index.js
 export { MediaProvider } from './MediaProvider'; 

主题上下文/context.js
和以前一样,创建createContextnpm module )。

 import createContext from 'create-react-context'; const { Provider, Consumer } = createContext(); export { Provider, Consumer }; 

我们导入,解构和导出生成的组件。

媒体上下文/constants.js
在此处保存变量。

 export const devices = ["mobile", "tablet", "desktop", "native"]; export const defaultDevice = "mobile"; 

在自适应方法中,用户主要使用4种类型的设备-台式机,平板电脑,移动设备和本机应用程序(本机)。 其他可能的设备:智能电视,时钟等。 在此示例中,我们将仅使用mobile和desktop

主题上下文/ MediaProvider / MediaProvider.js
我们已经知道,Provider在React.Context可用,它为上下文的消费者“提供”。 它使他们能够倾听并响应不断变化的环境。

道具是touchable device 。 让我提醒您,传递给value提供者的所有value将对消费者可用。

 import React from "react"; import PropTypes from "prop-types"; import { Provider } from "../context"; import { devices, defaultDevice } from "../constanst"; function MediaProvider(props) { const device = devices.includes(props.device) ? props.device : props.defaultDevice; return <Provider value={{ ...props, device }}>{props.children}</Provider>; } MediaProvider.propTypes = { device: PropTypes.oneOf(devices), touchable: false, children: PropTypes.node }; MediaProvider.defaultProps = { device: defaultDevice, touchable: false }; export { MediaProvider }; 

主题上下文/ MediaConsumer / MediaConsumer.js

消费者的功能描述可以在上一篇文章中找到,但简而言之, Consumer响应上下文并返回一个新组件。

在这种情况下,我们将两个参数传递给children :设备类型以及设备是否为触摸感应设备。

 import React from "react"; import PropTypes from "prop-types"; import { defaultTo } from "lodash"; import { devices, defaultDevice } from "../constanst"; import { Consumer } from '../context'; function MediaConsumer(props) { return ( <Consumer> {media => props.children({ touchable: defaultTo(media.touchable, props.defaultTouchable), device: defaultTo(media.device, props.defaultDevice), })} </Consumer> ) } MediaConsumer.propTypes = { defaultTouchable: PropTypes.bool, defaultDevice: PropTypes.oneOf(devices), children: PropTypes.func.isRequired }; MediaConsumer.defaultProps = { defaultDevice, defaultTouchable: false }; export { MediaConsumer }; 

现在,我们的应用程序中提供了一个新的上下文,让我们使用它。

 import React from "react"; import ReactDOM from "react-dom"; import { isMobile } from "react-device-detect"; import cx from "classnames"; import { ThemeConsumer, ThemeProvider } from "./theme-context"; import { MediaConsumer, MediaProvider } from "./media-context"; import "./styles.css"; function renderSVG({ device, touchable }) { if (device === "mobile" && touchable) { return "https://image.flaticon.com/icons/svg/124/124114.svg"; } if (device === "tablet" && touchable) { return "https://image.flaticon.com/icons/svg/124/124099.svg"; } if (device === "desktop") { return "https://image.flaticon.com/icons/svg/124/124092.svg"; } } function MyComponent() { const renderMyComponent = (theme, media) => { const myComponentClassName = cx("my-class", { "my-class-dark": theme === "dark", "my-class-light": theme === "light" }); return ( <div className="wrapperDiv"> <object className={myComponentClassName} data={renderSVG(media)} type="image/svg+xml" /> </div> ); }; return ( <MediaConsumer> {media => ( <ThemeConsumer> {theme => renderMyComponent(theme, media)} </ThemeConsumer> )} </MediaConsumer> ); } function App() { return ( <MediaProvider device={isMobile ? "mobile" : "desktop"} touchable={isMobile} > <ThemeProvider theme="light"> <MyComponent /> </ThemeProvider> </MediaProvider> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); 

要使用媒体竞赛,我们需要一个媒体检测器(以获取有关用户设备的信息)。 我们的应用程序中没有媒体检测器,因此让我们从这里开始-react-device-detect ,即isMobile标志。

与上下文主题一样,我们将测试组件包装在媒体提供程序中。 供应商传递到其帐户的道具的价值将使客户羡慕不已。 我从移动设备进入,我们从计算机-桌面发送网站的移动版本。 工作代码可以在这里找到

要查看区别,请通过台式机和移动浏览器访问链接。

仅此而已! 现在,我们的应用程序具有两个上下文,这将有助于我们在UI-Kit中创建更多功能和更灵活的组件。 在下一篇文章中,我将尝试使用这两种上下文创建一个复杂的组件。 希望本文对您有所帮助。

谢谢啦

Source: https://habr.com/ru/post/zh-CN463597/


All Articles