博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react 自定义控件使用_使用React构建自定义的拨动开关
阅读量:2507 次
发布时间:2019-05-11

本文共 29704 字,大约阅读时间需要 99 分钟。

react 自定义控件使用

Building web applications usually involves making provisions for user interactions. One of the major ways of making provision for user interactions is through forms. Different form components exist for taking different kinds of input from the user. For example, a password component takes sensitive information from a user and masks the information so that it is not visible.

构建Web应用程序通常涉及为用户交互做好准备。 提供用户交互的主要方法之一是通过表单。 存在用于接收来自用户的不同种类输入的不同表单组件。 例如,密码组件从用户那里获取敏感信息,并屏蔽该信息,使其不可见。

Most times, the information you need to get from a user is boolean-like - for example: yes or no, true or false, enable or disable, on or off, etc. Traditionally, the checkbox form component is used for getting these kinds of input. However, in modern interface designs, toggle switches are commonly used as checkbox replacements, although there are some accessibility concerns.

大多数时候,你需要从用户得到的信息是布尔 - 喜欢 -例如: 启用禁用 关闭等传统上,复选框表格组件用于得到这些输入。 但是,在现代界面设计中,尽管存在一些可访问性问题,但拨动开关通常用作复选框的替代品。

Checkbox vs Toggle Switch

In this tutorial, we will see how to build a custom toggle switch component with React. At the end of the tutorial, we would have built a very simple demo React app that uses our custom toggle switch component.

在本教程中,我们将看到如何使用React构建自定义切换开关组件。 在本教程的最后,我们将使用自定义的切换开关组件构建一个非常简单的演示React应用程序。

Here is a demo of the final application we will be building in this tutorial.

这是我们将在本教程中构建的最终应用程序的演示。

Application Demo

( )

Before getting started, you need to ensure that you have already installed on your machine. I will also recommend that you install the package manager on your machine, since we will be using it for package management instead of that ships with Node. You can follow this to install yarn on your machine.

在开始之前,您需要确保计算机上已经安装了 。 我还将建议您在计算机上安装软件包管理器,因为我们将使用它来进行软件包管理,而不是Node附带的 。 您可以按照此在机器上安装yarn

We will create the boilerplate code for our React app using the command-line package. You also need to ensure that it is installed globally on your machine. If you are using npm >= 5.2 then you may not need to install create-react-app as a global dependency since we can use the npx command.

我们将使用命令行软件包为React应用创建样板代码。 您还需要确保将其全局安装在您的计算机上。 如果您使用的是npm >= 5.2那么您可能不需要安装create-react-app作为全局依赖项,因为我们可以使用npx命令。

Finally, this tutorial assumes that you are already familiar with React. If that is not the case, you can check the to learn more about React.

最后,本教程假定您已经熟悉React。 如果不是这种情况,可以查看以了解有关React的更多信息。

( )

创建新的应用程序 (Create new Application)

Start a new React application using the following command. You can name the application however you desire.

使用以下命令启动一个新的React应用程序。 您可以根据需要命名应用程序。

create-react-app react-toggle-switch

npm **>= 5.2**

npm **> = 5.2 **

If you are using npm version 5.2 or higher, it ships with an additional npx binary. Using the npx binary, you don't need to install create-react-app` globally on your machine. You can start a new React application with this simple command:

如果您使用的是npm 5.2或更高版本,它将附带一个附加的npx二进制文件。 使用npx二进制文件,您无需在计算机上全局安装create-react-app`。 您可以使用以下简单命令启动新的React应用程序:

npx create-react-app react-toggle-switch
npx create-react-app react-toggle-switch

安装依赖项 (Install Dependencies)

Next, we will install the dependencies we need for our application. Run the following command to install the required dependencies.

接下来,我们将安装应用程序所需的依赖项。 运行以下命令以安装所需的依赖项。

yarn add lodash bootstrap prop-types classnamesyarn add -D npm-run-all node-sass-chokidar

We have installed node-sass-chokidar as a development dependency for our application to enable us use SASS. For more information about this, see .

我们已将node-sass-chokidar安装为应用程序的开发依赖项,以使我们能够使用SASS。 有关此的更多信息,请参阅 。

修改npm脚本 (Modify the npm Scripts)

Edit the package.json file and modify the scripts section to look like the following:

编辑package.json文件并修改scripts部分,使其如下所示:

"scripts" : {  "start:js" : "react-scripts start" ,  "build:js" : "react-scripts build" ,  "start" : "npm-run-all -p watch:css start:js" ,  "build" : "npm-run-all build:css build:js" ,  "test" : "react-scripts test --env=jsdom" ,  "eject" : "react-scripts eject" ,  "build:css" : "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/" ,  "watch:css" : "npm run build:css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive"}

包括Bootstrap CSS (Include Bootstrap CSS)

We installed the bootstrap package as a dependency for our application since we will be needing some default styling. To include Bootstrap in the application, edit the src/index.js file and add the following line before every other import statement.

我们将bootstrap软件包安装为应用程序的依赖项,因为我们将需要一些默认样式。 要将Bootstrap包含在应用程序中,请编辑src/index.js文件,并在所有其他import语句之前添加以下行。

import "bootstrap/dist/css/bootstrap.min.css" ;

启动应用程序 (Start the Application)

Start the application by running the following command with yarn:

通过对yarn运行以下命令来启动应用程序:

yarn start

The application is now started and development can begin. Notice that a browser tab has been opened for you with live reloading functionality to keep in sync with changes in the application as you develop.

现在,该应用程序已启动,可以开始开发了。 请注意,已为您打开了具有实时重新加载功能的浏览器选项卡,以在您开发时与应用程序中的更改保持同步。

At this point, the application view should look like the following screenshot:

此时,应用程序视图应类似于以下屏幕截图:

初始视图

( )

Create a new directory named components inside the src directory of your project. Next, create another new directory named ToggleSwitch inside the components directory. Next, create two new files inside src/components/ToggleSwitch, namely: index.js and index.scss.

在项目的src目录中创建一个名为components的新目录。 接下来,在components目录内创建另一个名为ToggleSwitch新目录。 接下来,在src/components/ToggleSwitch内创建两个新文件,即: index.jsindex.scss

Add the following content into the src/components/ToggleSwitch/index.js file.

将以下内容添加到src/components/ToggleSwitch/index.js文件中。

/ _ src / components / ToggleSwitch / index . js _ /import PropTypes from 'prop-types' ;import classnames from 'classnames' ;import isString from 'lodash/isString' ;import React , { Component } from 'react' ;import isBoolean from 'lodash/isBoolean' ;import isFunction from 'lodash/isFunction' ;import './index.css' ;class ToggleSwitch extends Component { }ToggleSwitch . propTypes = {  theme : PropTypes . string ,  enabled : PropTypes . oneOfType ( [    PropTypes . bool ,    PropTypes . func  ] ) ,  onStateChanged : PropTypes . func}export default ToggleSwitch ;

In this code snippet, we created the ToggleSwitch component and added typechecks for some of its props.

在此代码段中,我们创建了ToggleSwitch组件,并为其某些道具添加了类型检查。

  • theme - is a string indicating the style and color to be used for the toggle switch.

    theme是一个string指示用于拨动开关的样式和颜色。

  • enabled - can be either a boolean or a function that returns a boolean, and it determines the state of the toggle switch when it is rendered.

    enabled -可以是一个booleanfunction返回一个boolean ,它确定何时呈现所述拨动开关的状态。

  • onStateChanged - is a callback function that will be called when the state of the toggle switch changes. This is useful for triggering actions on the parent component when the switch is toggled.

    onStateChanged是一个回调函数,将在切换开关的状态更改时被调用。 当切换开关时,这对于触发父组件上的动作很有用。

初始化ToggleSwitch状态 (Initializing the ToggleSwitch State)

In the following code snippet, we initialize the state of the ToggleSwitch component and define some component methods for getting the state of the toggle switch.

在下面的代码片段中,我们初始化ToggleSwitch组件的状态,并定义一些组件方法来获取切换开关的状态。

/ _ src / components / ToggleSwitch / index . js _ /class ToggleSwitch extends Component {  state = { enabled : this . enabledFromProps ( ) }  isEnabled = ( ) => this . state . enabled  enabledFromProps ( ) {    let { enabled } = this . props ;    // If enabled is a function, invoke the function    enabled = isFunction ( enabled ) ? enabled ( ) : enabled ;    // Return enabled if it is a boolean, otherwise false    return isBoolean ( enabled ) && enabled ;  }}

Here, the enabledFromProps() method resolves the enabled prop that was passed and returns a boolean indicating if the switch should be enabled when it is rendered. If enabled prop is a boolean, it returns the boolean value. If it is a function, it first invokes the function before determining if the returned value is a boolean. Otherwise, it returns false.

在这里, enabledFromProps()方法解析传递的enabled prop,并返回一个boolean指示在渲染开关时是否应启用该开关。 如果enabled prop是boolean ,则返回布尔值。 如果它是一个function ,则在确定返回的值是否为布尔值之前,首先调用该函数。 否则,它返回false

Notice that we used the return value from enabledFromProps() to set the initial enabled state. Also, we have added the isEnabled() method to get the current enabled state.

请注意,我们使用了enabledFromProps()的返回值来设置初始enabled状态。 另外,我们添加了isEnabled()方法来获取当前的enabled状态。

切换ToggleSwitch (Toggling the ToggleSwitch)

Let's go ahead and add the method that actually toggles the switch when it is clicked.

让我们继续添加单击该开关时实际切换该开关的方法。

/ _ src / components / ToggleSwitch / index . js _ /class ToggleSwitch extends Component {  // ...other class members here  toggleSwitch = evt => {    evt . persist ( ) ;    evt . preventDefault ( ) ;    const { onClick , onStateChanged } = this . props ;    this . setState ( { enabled : ! this . state . enabled } , ( ) => {      const state = this . state ;      // Augument the event object with SWITCH_STATE      const switchEvent = Object . assign ( evt , { SWITCH_STATE : state } ) ;      // Execute the callback functions      isFunction ( onClick ) && onClick ( switchEvent ) ;      isFunction ( onStateChanged ) && onStateChanged ( state ) ;    } ) ;  }}

Since this method will be triggered as a click event listener, we have declared it with the evt parameter. First, this method toggles the current enabled state using the logical NOT (!) operator. When the state has been updated, it triggers the callback functions passed to the onClick and onStateChanged props.

由于此方法将作为click事件侦听器触发,因此我们已使用evt参数对其进行了声明。 首先,此方法使用逻辑NOT! )运算符切换当前enabled状态。 更新状态后,它会触发传递给onClickonStateChanged道具的回调函数。

Notice that since onClick requires an event as its first argument, we augmented the event with an additional SWITCH_STATE property containing the new state object. However, the onStateChanged callback is called with the new state object.

注意,由于onClick要求将事件作为其第一个参数,因此我们使用包含新状态对象的附加SWITCH_STATE属性扩展了该事件。 但是,使用新的状态对象调用onStateChanged回调。

渲染ToggleSwitch (Rendering the ToggleSwitch)

Finally, let's implement the render() method of the ToggleSwitch component.

最后,让我们实现ToggleSwitch组件的render()方法。

/ _ src / components / ToggleSwitch / index . js _ /class ToggleSwitch extends Component {  // ...other class members here  render ( ) {    const { enabled } = this . state ;    // Isolate special props and store the remaining as restProps    const { enabled : _enabled , theme , onClick , className , onStateChanged , ... restProps } = this . props ;    // Use default as a fallback theme if valid theme is not passed    const switchTheme = ( theme && isString ( theme ) ) ? theme : 'default' ;    const switchClasses = classnames (      `switch switch-- ${ switchTheme } ` ,      className    )    const togglerClasses = classnames (      'switch-toggle' ,      `switch-toggle-- ${ enabled ? 'on' : 'off' } `    )    return (      < div className = { switchClasses } onClick = { this . toggleSwitch } { ... restProps } >        < div className = { togglerClasses } > < / div >      < / div >    )  }}

A lot is going on in this render() method - so let's try to break it down.

这个render()方法正在进行很多工作-因此,让我们尝试对其进行分解。

  1. First, the enabled state is destructured from the component state.

    首先,使enabled状态从组件状态解构。

  2. Next, we destructure the component props and extract the restProps that will be passed down to the switch. This enables us to intercept and isolate the special props of the component.

    接下来,我们对组件restProps ,并提取restProps ,这些将被传递到开关。 这使我们能够拦截和隔离组件的特殊道具。

  3. Next, we use classnames to construct the classes for the switch and the inner toggler, based on the theme and the enabled state of the component.

    接下来,我们基于组件的themeenabled状态,使用类名来构造开关和内部切换器的类。

  4. Finally, we render the DOM elements with the appropriate props and classes. Notice that we passed in this.toggleSwitch as the click event listener on the switch.

    最后,我们使用适当的props和class渲染DOM元素。 注意,我们传入了this.toggleSwitch作为交换机上的click事件监听器。

( )

Now that we have the ToggleSwitch component and its required functionality, we will go ahead and write the styles for the toggle switch.

现在我们有了ToggleSwitch组件及其所需的功能,我们将继续为切换开关编写样式。

Add the following code snippet to the src/components/ToggleSwitch/index.scss file you created earlier:

将以下代码片段添加到您先前创建的src/components/ToggleSwitch/index.scss文件中:

/_ src/components/ToggleSwitch/index . scss _/// DEFAULT COLOR VARIABLES$ball-color : #ffffff ;$active-color : #62c28e ;$inactive-color : #cccccc ;// DEFAULT SIZING VARIABLES$switch-size : 32 px ;$ball-spacing : 2 px ;$stretch-factor : 1.625 ;// DEFAULT CLASS VARIABLE$switch-class : 'switch-toggle' ;/_ SWITCH MIXIN _/@mixin switch ( $size : $switch-size , $spacing : $ball-spacing , $stretch : $stretch-factor , $color : $active-color , $class : $switch-class ) { }

Here, we defined some default variables and created a switch mixin. In the next section, we will we will implement the mixin, but first, let's examine the parameters of the switch mixin:

在这里,我们定义了一些默认变量并创建了一个switch mixin。 在下一节中,我们将实现mixin,但首先,让我们检查一下switch mixin的参数:

  • $size - The height of the switch element. It must have a length unit. It defaults to 32px.

    $size开关元素的高度。 它必须具有长度单位。 默认为32px

  • $spacing - The space between the circular ball and the switch container. It must have a length unit. It defaults to 2px.

    $spacing圆形球和开关容器之间的空间。 它必须具有长度单位。 默认为2px

  • $stretch - A factor used to determine the extent to which the width of the switch element should be stretched. It must be a unitless number. It defaults to 1.625.

    $stretch一个因素,用于确定开关元件的宽度应拉伸的程度。 它必须是一个无单位的数字。 默认为1.625

  • $color - The color of the switch when in active state. This must be a valid color value. Note that the circular ball is always white irrespective of this color.

    $color处于活动状态时开关的颜色。 这必须是有效的颜色值。 请注意,圆形球始终是白色的,与该颜色无关。

  • $class - The base class for identifying the switch. This is used to dynamically create the state classes of the switch. It defaults to 'switch-toggle'. Hence, the default state classes are .switch-toggle--on and .switch-toggle--off.

    $class用于标识开关的基类。 这用于动态创建交换机的状态类。 默认为'switch-toggle' 。 因此,默认状态类为.switch-toggle--on.switch-toggle--off

实施开关Mixin (Implementing the Switch Mixin)

Here is the implementation of the switch mixin:

这是switch mixin的实现:

/_ src/components/ToggleSwitch/index . scss _/@mixin switch ( $size : $switch-size , $spacing : $ball-spacing , $stretch : $stretch-factor , $color : $active-color , $class : $switch-class ) {  // SELECTOR VARIABLES  $self : '.' + $class ;  $on : #{$self} --on ;  $off : #{$self} --off ;  // SWITCH VARIABLES  $active-color : $color ;  $switch-size : $size ;  $ball-spacing : $spacing ;  $stretch-factor : $stretch ;  $ball-size : $switch-size - ( $ball-spacing _ 2 ) ;  $ball-slide-size : ( $switch-size _ ( $stretch-factor - 1 ) + $ball-spacing ) ;  // SWITCH STYLES  height : $switch-size ;  width : $switch-size * $stretch-factor ;  cursor : pointer !important ;  user-select : none !important ;  position : relative !important ;  display : inline-block ;  & #{$on} ,  & #{$off}  {    & ::before,    & ::after  {      content : '' ;      left : 0 ;      position : absolute !important ;    }    & ::before  {      height : inherit ;      width : inherit ;      border-radius : $switch-size / 2 ;      will-change : background ;      transition : background .4 s .3 s ease-out ;    }    & ::after  {      top : $ball-spacing ;      height : $ball-size ;      width : $ball-size ;      border-radius : $ball-size / 2 ;      background : $ball-color !important ;      will-change : transform ;      transition : transform .4 s ease-out ;    }  }  & #{$on}  {    & ::before  {      background : $active-color !important ;    }    & ::after  {      transform : translateX ( $ball-slide-size ) ;    }  }  & #{$off}  {    & ::before  {      background : $inactive-color !important ;    }    & ::after  {      transform : translateX ( $ball-spacing ) ;    }  }}

In this mixin, we start by setting some variables based on the parameters passed to the mixin. Then we go ahead, creating the styles. Notice that we are using the ::after and ::before pseudo-elements to dynamically create the components of the switch. ::before creates the switch container while ::after creates the circular ball.

在此mixin中,我们首先基于传递给mixin的参数设置一些变量。 然后,我们继续创建样式。 注意,我们使用::after::before伪元素来动态创建开关的组件。 ::before创建开关容器,而::after创建圆形球。

Also notice how we constructed the state classes from the base class and assign them to variables. The $on variable maps to the selector for the enabled state, while the $off variable maps to the selector for the disabled state.

还要注意我们如何从基类构造状态类并将其分配给变量。 $on变量映射到启用状态的选择器,而$off变量映射到禁用状态的选择器。

We also ensured that the base class (.switch-toggle) must be used together with a state class (.switch-toggle--on or .switch-toggle--off) for the styles to be available. Hence, we used the &#{$on} and &#{$off} selectors.

我们还确保必须使用基类( .switch-toggle )和状态类( .switch-toggle--on.switch-toggle--off )才能使用样式。 因此,我们使用了&#{$on}&#{$off}选择器。

创建主题开关 (Creating Themed Switches)

Now that we have our switch mixin, we will continue to create some themed styles for the toggle switch. We will create two themes, namely: default and graphite-small.

现在我们有了switch mixin,我们将继续为切换开关创建一些主题样式。 我们将创建两个主题,即: defaultgraphite-small

Append the following code snippet to the src/components/ToggleSwitch/index.scss file.

将以下代码段追加到src/components/ToggleSwitch/index.scss文件中。

/_ src/components/ToggleSwitch/index . scss _/@function get-switch-class ( $selector ) {  // First parse the selector using `selector-parse`  // Extract the first selector in the first list using `nth` twice  // Extract the first simple selector using `simple-selectors` and `nth`  // Extract the class name using `str-slice`  @return str-slice ( nth ( simple-selectors ( nth ( nth ( selector-parse ( $selector ) , 1 ) , 1 ) ) , 1 ) , 2 ) ;}.switch  {  $self : & ;  $toggle : #{$self} -toggle ;  $class : get-switch-class ( $toggle ) ;  // default theme  & #{$self} --default > #{$toggle}  {    // Always pass the $class to the mixin    @include switch ( $class : $class ) ;  }  // graphite-small theme  & #{$self} --graphite-small > #{$toggle}  {    // A smaller switch with a `gray` active color    // Always pass the $class to the mixin    @include switch ( $color : gray, $size : 20 px, $class : $class ) ;  }}

Here we first create a Sass function named get-switch-class that takes a $selector as parameter. It runs the $selector through a chain of Sass functions and tries to extract the first class name. For example, if it receives:

在这里,我们首先创建一个名为get-switch-class的Sass函数,该函数将$selector作为参数。 它通过一系列Sass函数运行$selector ,并尝试提取第一个类名。 例如,如果收到:

  • .class-1 .class-2, .class-3 .class-4, it returns class-1.

    .class-1 .class-2, .class-3 .class-4 ,它返回class-1

  • .class-5.class-6 > .class-7.class-8, it returns class-5.

    .class-5.class-6 > .class-7.class-8 ,它返回class-5

Next, we define styles for the .switch class. We dynamically set the toggle class to .switch-toggle and assign it to the $toggle variable. Notice that we assign the class name returned from the get-switch-class() function call to the $class variable. Finally, we include the switch mixin with the necessary parameters to create the theme classes.

接下来,我们为.switch类定义样式。 我们将toggle类动态设置为.switch-toggle并将其分配给$toggle变量。 请注意,我们将从get-switch-class()函数调用返回的类名称分配给$class变量。 最后,我们包括带有必要参数的switch mixin来创建主题类。

Notice that the structure of the selector for the themed switch looks like this: &#{$self}--default > #{$toggle} (using the default theme as an example). Putting everything together, this means that the elements hierarchy should look like the following in order for the styles to be applied:

请注意,主题开关的选择器的结构如下所示: &#{$self}--default > #{$toggle}以默认主题为例 )。 将所有内容放在一起,这意味着要应用样式,元素层次结构应类似于以下内容:

< element class = " switch switch--default " >
< element class = " switch-toggle switch-toggle--on " >

Here is a simple demo showing what the toggle switch themes look like:

这是一个简单的演示,显示了切换开关主题的外观:

切换主题

( )

Now that we have the ToggleSwitch React component with the required styling, let's go ahead and start creating the sample app we saw at the beginning section.

现在我们有了具有所需样式的ToggleSwitch React组件,让我们继续创建在开始部分看到的示例应用程序。

Modify the src/App.js file to look like the following code snippet:

修改src/App.js文件,使其看起来像以下代码片段:

/ _ src / App . js _ /import classnames from 'classnames' ;import snakeCase from 'lodash/snakeCase' ;import React , { Component } from 'react' ;import Switch from './components/ToggleSwitch' ;import './App.css' ;// List of activities that can trigger notificationsconst ACTIVITIES = [  'News Feeds' , 'Likes and Comments' , 'Live Stream' , 'Upcoming Events' ,  'Friend Requests' , 'Nearby Friends' , 'Birthdays' , 'Account Sign-In'] ;class App extends Component {  // Initialize app state, all activities are enabled by default  state = { enabled : false , only : ACTIVITIES . map ( snakeCase ) }  toggleNotifications = ( { enabled } ) => {    const { only } = this . state ;    this . setState ( { enabled , only : enabled ? only : ACTIVITIES . map ( snakeCase ) } ) ;  }  render ( ) {    const { enabled } = this . state ;    const headingClasses = classnames (      'font-weight-light h2 mb-0 pl-4' ,      enabled ? 'text-dark' : 'text-secondary'    ) ;    return (      < div className = "App position-absolute text-left d-flex justify-content-center align-items-start pt-5 h-100 w-100" >        < div className = "d-flex flex-wrap mt-5" style = { { width : 600 } } >          < div className = "d-flex p-4 border rounded align-items-center w-100" >            < Switch theme = "default"              className = "d-flex"              enabled = { enabled }              onStateChanged = { this . toggleNotifications }            / >            < span className = { headingClasses } > Notifications < / span >          < / div >          { /_ ...Notification options here... _/ }        < / div >      < / div >    ) ;  }}export default App ;

Here we initialize the ACTIVITIES constant with an array of activities that can trigger notifications. Next, we initialized the app state with two properties:

在这里,我们使用一系列可以触发通知的活动来初始化ACTIVITIES常量。 接下来,我们使用两个属性初始化应用程序状态:

  • enabled - a boolean that indicates whether notifications are enabled.

    enabled一个boolean ,指示是否启用通知。

  • only - an array that contains all the activities that are enabled to trigger notifications.

    only -包含所有启用以触发通知的活动的array

Notice that we used the snakeCase utility from Lodash to convert the activities to snakecase before updating the state. Hence, 'News Feeds' becomes 'news_feeds'.

注意,在更新状态之前,我们使用了snakeCase实用程序将活动转换为snakecase。 因此, 'News Feeds'变为'news_feeds'

Next, we defined the toggleNotifications() method that updates the app state based on the state it receives from the notification switch. This is used as the callback function passed to the onStateChanged prop of the toggle switch. Notice that when the app is enabled, all activities will be enabled by default, since the only state property is populated with all the activities.

接下来,我们定义了toggleNotifications()方法,该方法根据从通知开关接收到的状态来更新应用程序状态。 用作传递到切换开关的onStateChanged的回调函数。 请注意,启用该应用程序后,默认情况下将启用所有活动,因为only state属性填充了所有活动。

Finally, we rendered the DOM elements for the app and left a slot for the notification options which will be added soon. At this point, the app should look like the following screenshot:

最后,我们为应用程序渲染了DOM元素,并为通知选项留出了一个插槽,这些选项将很快添加。 此时,该应用程序应类似于以下屏幕截图:

初始应用程序视图

Next go ahead and look for the line that has this comment:

接下来继续查找具有此注释的行:

{ /_ ...Notification options here... _/ }

and replace it with the following content in order to render the notification options:

并将其替换为以下内容,以呈现通知选项:

{ enabled && (  < div className = "w-100 mt-5" >    < div className = "container-fluid px-0" >      < div className = "pt-5" >        < div className = "d-flex justify-content-between align-items-center" >          < span className = "d-block font-weight-bold text-secondary small" > Email Address < / span >          < span className = "text-secondary small mb-1 d-block" >            < small > Provide a valid email address with which to receive notifications . < / small >          < / span >        < / div >        < div className = "mt-2" >          < input type = "text" placeholder = "mail@domain.com" className = "form-control" style = { { fontSize : 14 } } / >        < / div >      < / div >      < div className = "pt-5 mt-4" >        < div className = "d-flex justify-content-between align-items-center border-bottom pb-2" >          < span className = "d-block font-weight-bold text-secondary small" > Filter Notifications < / span >          < span className = "text-secondary small mb-1 d-block" >            < small > Select the account activities for which to receive notifications . < / small >          < / span >        < / div >        < div className = "mt-5" >          < div className = "row flex-column align-content-start" style = { { maxHeight : 180 } } >            { this . renderNotifiableActivities ( ) }          < / div >        < / div >      < / div >    < / div >  < / div >) }

Notice here that we made a call to this.renderNotifiableActivities() to render the activities. Let's go ahead and implement this method and the other remaining methods.

注意这里我们调用了this.renderNotifiableActivities()来渲染活动。 让我们继续实现此方法和其他其余方法。

Add the following methods to the App component.

将以下方法添加到App组件。

/ _ src / App . js _ /class App extends Component {  toggleActivityEnabled = activity => ( { enabled } ) => {    let { only } = this . state ;    if ( enabled && ! only . includes ( activity ) ) {      only . push ( activity ) ;      return this . setState ( { only } ) ;    }    if ( ! enabled && only . includes ( activity ) ) {      only = only . filter ( item => item !== activity ) ;      return this . setState ( { only } ) ;    }  }  renderNotifiableActivities ( ) {    const { only } = this . state ;    return ACTIVITIES . map ( ( activity , index ) => {      const key = snakeCase ( activity ) ;      const enabled = only . includes ( key ) ;      const activityClasses = classnames (        'small mb-0 pl-3' ,        enabled ? 'text-dark' : 'text-secondary'      ) ;      return (        < div key = { index } className = "col-5 d-flex mb-3" >          < Switch theme = "graphite-small"            className = "d-flex"            enabled = { enabled }            onStateChanged = { this . toggleActivityEnabled ( key ) }          / >          < span className = { activityClasses } > { activity } < / span >        < / div >      ) ;    } )  }}

Here, we have implemented the renderNotifiableActivities method. We iterate through all the activities using ACTIVITIES.map() and render each with a toggle switch for it. Notice that the toggle switch uses the graphite-small theme. We also detect the enabled state of each activity by checking whether it already exists in the only state variable.

在这里,我们实现了renderNotifiableActivities方法。 我们使用ACTIVITIES.map()遍历所有活动,并使用切换开关对其进行呈现。 请注意,拨动开关使用graphite-small主题。 我们还通过检查每个活动的enabled状态是否已经存在于only状态变量中来对其进行检测。

Finally, we defined the toggleActivityEnabled method which was used to provide the callback function for the onStateChanged prop of each activity's toggle switch. We defined it as a higher-order function so that we can pass the activity as argument and return the callback function. It checks if an activity is already enabled and updates the state accordingly.

最后,我们定义了toggleActivityEnabled方法,该方法用于为每个活动的切换开关的onStateChanged toggleActivityEnabled提供回调函数。 我们将其定义为高阶函数,以便我们可以将活动作为参数传递并返回回调函数。 它检查活动是否已启用,并相应地更新状态。

Now the app should look like the following screenshot:

现在,该应用程序应类似于以下屏幕截图:

最终应用视图

If you prefer to have all the activities disabled by default instead of enabled as shown in the initial screenshot, then you could make the following changes to the App component:

如果您希望默认禁用所有活动,而不是如初始屏幕快照中所示启用所有活动,则可以对App组件进行以下更改:

/ _ src / App . js _ /class App extends Component {  // Initialize app state, all activities are disabled by default  state = { enabled : false , only : [ ] }  toggleNotifications = ( { enabled } ) => {    const { only } = this . state ;    this . setState ( { enabled , only : enabled ? only : [ ] } ) ;  }}

( )

Using toggle switches in our applications instead of traditional checkboxes can enable us create neater interfaces, especially considering the fact that it is difficult to style a traditional checkbox however we want.

在我们的应用程序中使用拨动开关代替传统的复选框可以使我们创建更整洁的界面,尤其是考虑到难以根据需要设置传统复选框的样式这一事实。

However, using toggle switches instead of checkboxes has some accessibility issues, since the user-agent may not be able to interpret the component's function correctly.

但是,使用切换开关而不是复选框存在一些可访问性问题,因为用户代理可能无法正确解释组件的功能。

A few things can be done to improve the accessibility of the toggle switch and enable user-agents to understand the role correctly. For example, you can use the following ARIA attributes:

可以做一些事情来改善拨动开关的可访问性,并使用户代理能够正确理解角色。 例如,您可以使用以下ARIA属性:

< switch-element tabindex = " 0 " role = " switch " aria-checked = " true " aria-labelledby = " #label-element " > 

You can also listen to more events on the toggle switch to create more ways the user can interact with the component.

您还可以在拨动开关上收听更多事件,以创建用户与组件进行交互的更多方式。

( )

In this tutorial, we have been able to create a custom toggle switch for our React applications with proper styling that supports different themes. We have also been able to see how we can use it in our application instead of traditional checkboxes and the accessibility concerns involved.

在本教程中,我们已经能够使用支持不同主题的适当样式为React应用程序创建自定义切换开关。 我们还能够看到如何在应用程序中使用它,而不是使用传统的复选框以及涉及的可访问性问题。

For the complete sourcecode of this tutorial, checkout the repository on Github. You can also get a .

有关本教程的完整源代码,请检查Github上的存储库。 您还可以获得的 。

翻译自:

react 自定义控件使用

转载地址:http://xiuwd.baihongyu.com/

你可能感兴趣的文章
《Apache服务之php/perl/cgi语言的支持》RHEL6——服务的优先级
查看>>
Linux 部署 Django 系统
查看>>
java 异常处理2
查看>>
Bugku Crack it
查看>>
[React] Recompose: Theme React Components Live with Context
查看>>
[React] Creating a Stateless Functional Component
查看>>
python字符串截取子串
查看>>
【Android】Linux编译环境OpenJDK的版本修改到1.8
查看>>
【Spring】17、spring cache 与redis缓存整合
查看>>
【Linux命令】ps命令
查看>>
CentOS6.x的163yum配置
查看>>
C#中ref和out的使用小结
查看>>
Powershell-远程操作
查看>>
Java基础学习笔记二十一 多线程
查看>>
使用Java Low Level REST Client操作elasticsearch
查看>>
css3 抖动
查看>>
移动端手势
查看>>
[Linked List]Insertion Sort List
查看>>
Product of Array Except Self
查看>>
[Tree]Binary Tree Inorder Traversal
查看>>