基于React Hooks封装的验证码组件

简介: 基于React Hooks封装的验证码组件

一、概述


现在项目中一般涉及到用户登录都支持了手机验证码登录,本篇文章就是给大家分享一下胡哥封装的一个验证码组件rc-codebox,采用的是React Hooks的方式来开发的。


二、验证码组件介绍与安装


rc-codebox是基于react hooks的验证码组件,支持特性如下:


API


Name Description Type Default
len 验证码的位数 number 6
onChange 验证码改变时的callback (code: string) => void --
className 自定义类名 string --
autoFocus 是否自动获取焦点 boolean true


安装:


yarn add rc-codebox


使用:


import React, { useState } from 'react';
import { CodeBox } from 'rc-codebox';
export default () => {
  // 初始化code变量,接收验证码
  const [code, setCode] = useState('');
  /**
   * @method onChange
   * @description 检测用户输入的验证码
   */
  const onChange = (code) => {
    setCode(code);
  };
  return (
    <div>
      <h3>现在输入的code是:{code}</h3>
      {/* 渲染codeBox,指定验证码长度,自动获取焦点,检测用户输入验证码时的onChange事件 */}
      <CodeBox len={6} onChange={onChange} autoFocus={true}></CodeBox>
    </div>
  );
};


三、验证码组件设计与开发


rc-codebox验证码组件是基于组件开发工具dumi开发的。


在这里必须给dumi吹一波,dumi-为组件开发场景而生的文档工具,有几个非常优秀的特点:


  1. API文档自动生成,这个功能个人感觉太棒了,直接根据组件内部注释、TypeScript类型描述自动生成API文档,始终保持如一。免去了开发完组件还得写文档的烦恼,对程序员简直不要太好~


  1. 丰富的Markdown扩展,可以方便的渲染组件demo,支持文档编写、管理,主题可以定制多个


搭建组件项目:


# 初始化一个站点模式的组件库开发脚手架 - 当将项目推送到github时可以使用相关配置生成一个站点
yarn create @umijs/dumi-lib --site


验证码组件开发


import React, { useRef, useEffect } from 'react';
import './index.less';
interface CodeBoxProps {
  /**
   * @description 验证码的位数
   * @default 6
   */
  len?: number;
  /**
   * @description 验证码改变时的callback
   */
  onChange?: (code: string) => void;
  /**
   * @description 自定义类名
   *
   */
  className?: string;
  /**
   * @description 是否自动获取焦点
   * @default true
   */
  autoFocus?: boolean;
}
export function CodeBox(props: CodeBoxProps) {
  // 配置相关默认值
  const { len = 6, onChange, className = '', autoFocus = true } = props;
  // 输入框数组
  const inputArr = new Array(len).fill('');
  // 输入框ref
  const inputRefs = useRef<any>([]);
  /**
   * @method getRef
   * @description 获取input的ref
   */
  const getRef = (dom: any) => {
    if (inputRefs?.current?.length === len) {
      return;
    }
    inputRefs.current.push(dom);
  };
  /**
   * @method onInputKeyDown
   * @method 处理input的删除事件
   * @param e 事件
   * @param index number input输入框对应的索引
   */
  const onInputKeyDown = (e: any, index: number) => {
    switch (e.key) {
      case 'Backspace':
        if (index > 0 && !e.target.value) {
          const currentInputRef = inputRefs.current[index];
          currentInputRef.value = '';
          const prevInputRef = inputRefs.current[index - 1];
          prevInputRef.focus();
          // prevInputRef.select();
          e.preventDefault();
        }
        break;
    }
  };
  /**
   * @method onInputValueChange
   * @description 当输入的验证码发生变化时
   * @param index number input输入框对应的索引
   */
  const onInputValueChange = (index: number, e: any) => {
    let code = '';
    inputRefs.current?.forEach((ref: any) => {
      if (ref?.value) {
        code += ref?.value;
      } else {
        code += ' ';
      }
    });
    // 判断是删除操作
    if (index > 0 && !e.target.value) {
      const prevInputRef = inputRefs.current[index - 1];
      prevInputRef.focus();
    }
    // 判断是写入操作
    if (index < len - 1 && e.target.value) {
      const nextInputRef = inputRefs.current[index + 1];
      nextInputRef.focus();
    }
    onChange && onChange(code);
  };
  /**
   * @method getInputClassName
   * @description 动态获取每个验证码输入框的类名,增加已输入码的输入框样式
   * @param index number 索引
   * @returns string
   */
  const getInputClassName = (index: number) => {
    const currentInputRef = inputRefs.current[index];
    const value = currentInputRef?.value;
    const defaultClassName = 'code-box-input';
    return value ? defaultClassName + ' has-string' : defaultClassName;
  };
  useEffect(() => {
    // 自动获取焦点的处理
    if (autoFocus) {
      inputRefs?.current[0].focus();
    }
  }, [autoFocus]);
  return (
    <div className={className ? `code-box ${className}` : 'code-box'}>
      {/* 渲染每一个验证码输入框 */}
      {inputArr.map((v, index) => {
        return (
          <input
            ref={getRef}
            maxLength={1}
            className={getInputClassName(index)}
            key={index}
            type="text"
            onFocus={() => {
              inputRefs.current[index].select();
            }}
            onKeyDown={(e) => {
              onInputKeyDown(e, index);
            }}
            onChange={(e) => {
              onInputValueChange(index, e);
            }}
          />
        );
      })}
    </div>
  );
}
export default CodeBox;


index.less文件


.code-box {
  display: flex;
  flex-direction: row;
  &-input {
    width: 30px;
    margin-right: 10px;
    color: #333;
    font-size: 36px;
    text-align: center;
    border: none;
    border-bottom: 2px solid #ccc;
    outline: none;
    &.has-string {
      border-color: #575866;
    }
  }
}


这里是less样式


具体效果可以点击这里的传送门查看效果!


相关文章
|
2月前
|
前端开发 JavaScript
React Hooks 全面解析
【10月更文挑战第11天】React Hooks 是 React 16.8 引入的新特性,允许在函数组件中使用状态和其他 React 特性,简化了状态管理和生命周期管理。本文从基础概念入手,详细介绍了 `useState` 和 `useEffect` 的用法,探讨了常见问题和易错点,并提供了代码示例。通过学习本文,你将更好地理解和使用 Hooks,提升开发效率。
70 4
|
17天前
|
前端开发 JavaScript 测试技术
React 分页组件 Pagination
本文介绍了如何在 React 中从零构建分页组件,涵盖基础概念、常见问题及解决方案。通过示例代码详细讲解了分页按钮的创建、分页按钮过多、初始加载慢、状态管理混乱等常见问题的解决方法,以及如何避免边界条件、性能优化和用户反馈等方面的易错点。旨在帮助开发者更好地理解和掌握 React 分页组件的开发技巧,提升应用的性能和用户体验。
53 0
|
22天前
|
移动开发 前端开发 API
React 拖拽组件 Drag & Drop
本文介绍了在 React 中实现拖拽功能的方法,包括使用原生 HTML5 Drag and Drop API 和第三方库 `react-dnd`。通过代码示例详细讲解了基本的拖拽实现、常见问题及易错点,帮助开发者更好地理解和应用拖拽功能。
55 9
|
16天前
|
前端开发 UED 开发者
React 分页组件 Pagination
本文介绍了如何在 React 中实现分页组件,从基础概念到常见问题及解决方案。分页组件用于将大量数据分成多个页面,提升用户体验。文章详细讲解了分页组件的基本结构、快速入门步骤、以及如何处理页面跳转不平滑、页码过多导致布局混乱、边界条件处理和数据加载延迟等问题。通过本文,读者可以全面了解并掌握 React 分页组件的开发技巧。
28 2
|
20天前
|
设计模式 前端开发 编译器
与普通组件相比,React 泛型组件有哪些优势?
与普通组件相比,React 泛型组件有哪些优势?
32 6
|
20天前
|
前端开发 JavaScript
深入探索React Hooks:从useState到useEffect
深入探索React Hooks:从useState到useEffect
|
29天前
|
前端开发 JavaScript 安全
学习如何为 React 组件编写测试:
学习如何为 React 组件编写测试:
37 2
|
1月前
|
前端开发 JavaScript 开发者
“揭秘React Hooks的神秘面纱:如何掌握这些改变游戏规则的超能力以打造无敌前端应用”
【10月更文挑战第25天】React Hooks 自 2018 年推出以来,已成为 React 功能组件的重要组成部分。本文全面解析了 React Hooks 的核心概念,包括 `useState` 和 `useEffect` 的使用方法,并提供了最佳实践,如避免过度使用 Hooks、保持 Hooks 调用顺序一致、使用 `useReducer` 管理复杂状态逻辑、自定义 Hooks 封装复用逻辑等,帮助开发者更高效地使用 Hooks,构建健壮且易于维护的 React 应用。
32 2
|
2月前
|
前端开发 JavaScript 测试技术
React 高阶组件 (HOC) 应用
【10月更文挑战第16天】高阶组件(HOC)是 React 中一种复用组件逻辑的方式,通过接受一个组件并返回新组件来实现。本文介绍了 HOC 的基础概念、核心功能和常见问题,包括静态方法丢失、ref 丢失、多个 HOC 组合和 props 冲突的解决方案,并提供了具体的 React 代码示例。通过本文,读者可以更好地理解和应用 HOC,提高代码的复用性和可维护性。
63 8
|
2月前
|
前端开发 开发者
React 提供的其他重要 Hooks
【10月更文挑战第20天】React 提供了一系列强大的 Hooks,除了 `useRef` 之外,还有许多其他重要的 Hooks,它们共同构成了函数式组件开发的基础。
35 6