React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > React组件校验手机号格式

字节封装React组件手机号自动校验格式FormItem

作者:一袋米要扛几楼

这篇文章主要为大家介绍了字节封装React组件手机号自动校验格式FormItem,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

Situation 背景

Target 目标

Action 行动

import type {
  FormItemProps,
  InputProps,
  RulesProps,
} from '@arco-design/web-react';
import { Form, Input } from '@arco-design/web-react';
import { usePersistCallback } from '@byted/hooks';
import type { ReactNode } from 'react';
import { useMemo } from 'react';
export type VerifyInputProps = {
  /** 🔥 绑定属性 */
  field: string;
  /** 🔥 显示标签文字 */
  label: string;
  /** 标签前面是否显示必填*号 */
  labelRequired?: boolean;
  /** 🔥 rules是否加入必填校验(为true时无需再设置labelRequired=true) */
  phoneRequired?: boolean;
  /** 除检验手机号格式外其他规则,默认添加正则检验/^1[2-9]\d{9}$/ */
  rules?: RulesProps<any>[];
  /** 显示提示文字 */
  placeholder?: string;
  /** 是否禁用input */
  disabled?: boolean;
  /** phone输入框onChange事件 */
  onChange?: InputProps['onChange'];
  /** FormItem其他属性 */
  formItemProps?: FormItemProps;
  /** Input其他属性 */
  inputProps?: InputProps;
};
/** 手机号表单(带有 Form.Item) */
export const VerifyPhoneInput = (props: VerifyInputProps) => {
  const {
    field,
    label,
    placeholder,
    rules = [],
    labelRequired = false,
    phoneRequired = false,
    disabled,
    onChange,
    formItemProps,
    inputProps,
  } = props;
  const resultRules = useMemo(() => {
    const arr = [
      {
        validator(val: string | undefined, cb: (error?: ReactNode) => void) {
          const realVal = (`${val}` as any).replaceAll(' ', '');
          if (!val || /^1[2-9]\d{9}$/.test(realVal)) {
            cb();
          } else {
            cb(`请输入正确的${label}`);
          }
        },
      },
      ...rules,
    ];
    if (phoneRequired) {
      arr.unshift({
        validator(val: string | undefined, cb: (error?: ReactNode) => void) {
          if (!val) {
            cb(`请输入${label}`);
          } else {
            cb();
          }
        },
      });
    }
    return arr;
  }, [rules, phoneRequired, label]);
  const normalize = usePersistCallback((val: string | undefined) => {
    if (val) {
      const realVal = (`${val}` as any).replaceAll(' ', '');
      if (val !== realVal) {
        return realVal;
      }
    }
    return val;
  });
  const resultInputProps = {
    disabled,
    onChange,
    allowClear: true,
    placeholder: placeholder || `请输入${label}`,
    ...inputProps,
  };
  return (
    <Form.Item
      required={labelRequired || phoneRequired}
      field={field}
      label={label}
      formatter={normalize}
      rules={resultRules}
      {...formItemProps}
    >
      <Input {...resultInputProps} />
    </Form.Item>
  );
};

Result 结果

Review 复盘

import type { FormItemProps, InputProps } from '@arco-design/web-react';
import { Form, Input } from '@arco-design/web-react';
import { usePersistCallback } from '@byted/hooks';
import type { ReactNode } from 'react';
import { useMemo } from 'react';
const defaultLabel = '手机号码';
export type PhoneFormItemProps = {
  /** 🔥 rules是否加入必填校验(为true时无需再设置labelRequired=true) */
  phoneRequired?: boolean;
  /** 🔥 rules是否加入正则校验(/^1[2-9]\d{9}$/),默认true */
  phoneFormatCheck?: boolean;
  /** Input其他属性 */
  inputProps?: InputProps;
} & FormItemProps;
/** 手机号表单(带有 Form.Item) */
export const PhoneFormItem = (props: PhoneFormItemProps) => {
  const {
    phoneRequired = false,
    phoneFormatCheck = true,
    inputProps,
    ...formItemProps
  } = props;
  const resultRules = useMemo(() => {
    const arr = [...(formItemProps.rules || [])];
    if (phoneFormatCheck) {
      arr.unshift({
        validator(val: string | undefined, cb: (error?: ReactNode) => void) {
          const realVal = (`${val}` as any).replaceAll(' ', '');
          if (!val || /^1[2-9]\d{9}$/.test(realVal)) {
            cb();
          } else {
            cb(`请输入正确的${formItemProps?.label || defaultLabel}`);
          }
        },
      });
    }
    if (phoneRequired) {
      arr.unshift({
        validator(val: string | undefined, cb: (error?: ReactNode) => void) {
          if (!val) {
            cb(`请输入${formItemProps.label || defaultLabel}`);
          } else {
            cb();
          }
        },
      });
    }
    return arr;
  }, [
    formItemProps.rules,
    formItemProps.label,
    phoneFormatCheck,
    phoneRequired,
  ]);
  const normalize = usePersistCallback((val: string | undefined) => {
    if (val) {
      const realVal = (`${val}` as any).replaceAll(' ', '');
      if (val !== realVal) {
        return realVal;
      }
    }
    return val;
  });
  const resultInputProps = {
    allowClear: true,
    ...inputProps,
    placeholder:
      inputProps?.placeholder || `请输入${formItemProps.label || defaultLabel}`,
  };
  return (
    <Form.Item
      normalize={normalize}
      rules={resultRules}
      {...formItemProps}
      required={formItemProps.required || phoneRequired}
    >
      <Input {...resultInputProps} />
    </Form.Item>
  );
};

以前都是用vue,来字节之后天天react,感觉自己变菜了好多,又或许我原本就菜的离谱。

以上就是字节封装React组件手机号自动校验格式FormItem的详细内容,更多关于React封装手机号校验格式的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文