Text Mask与React Native集成:移动应用输入格式化方案

【免费下载链接】text-mask Input mask for React, Angular, Ember, Vue, & plain JavaScript 【免费下载链接】text-mask 项目地址: https://gitcode.com/gh_mirrors/te/text-mask

在移动应用开发中,用户输入格式化是提升体验的关键环节。电话号码、信用卡号、日期等信息若缺乏即时格式化,不仅影响用户体验,还可能导致数据错误。Text Mask作为一款支持React、Angular等多框架的输入格式化库,其核心功能通过core/src/conformToMask.js实现输入内容与掩码规则的匹配,为移动应用提供了可靠的解决方案。

核心适配原理

Text Mask的React Native集成基于其Web版本核心逻辑改造。Web端通过react/src/reactTextMask.js实现组件封装,而React Native需针对TextInput组件特性调整事件处理机制。关键适配点包括:

  1. 输入事件绑定
    替换Web端的input事件监听,使用React Native TextInput的onChangeText回调触发格式化:

    <TextInput
      onChangeText={text => {
        const { conformedValue } = conformToMask(text, mask)
        setFormattedValue(conformedValue)
      }}
    />
    
  2. 光标位置管理
    利用core/src/adjustCaretPosition.js算法,在格式化后重新计算光标位置,避免输入中断感。

  3. 跨平台掩码兼容性
    复用addons/src/createNumberMask.js等预置掩码生成器,确保移动端与Web端格式化规则一致。

实现步骤

1. 基础组件封装

创建MaskedTextInput组件,整合Text Mask核心功能:

import React, { useState, useCallback } from 'react';
import { TextInput } from 'react-native';
import conformToMask from '../core/src/conformToMask';
import createNumberMask from '../addons/src/createNumberMask';

const phoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];

export const MaskedTextInput = ({ mask = phoneMask, ...props }) => {
  const [value, setValue] = useState('');
  
  const handleChange = useCallback((text) => {
    const { conformedValue } = conformToMask(text, mask);
    setValue(conformedValue);
  }, [mask]);

  return <TextInput value={value} onChangeText={handleChange} {...props} />;
};

2. 高级掩码配置

通过createNumberMask实现带千分位的金额格式化:

const currencyMask = createNumberMask({
  prefix: '¥',
  includeThousandsSeparator: true,
  thousandsSeparatorSymbol: ',',
  allowDecimal: true,
  decimalLimit: 2
});

// 使用:<MaskedTextInput mask={currencyMask} keyboardType="numeric" />

3. 动态掩码切换

根据用户输入动态调整掩码规则,如国际电话号码:

const getPhoneMask = (value) => {
  if (value.startsWith('+1')) return ['+', '1', ' ', '(', /\d/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
  return ['+', /\d/, ' ', /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, /\d/, /\d/];
};

// 使用:<MaskedTextInput mask={getPhoneMask} />

效果对比

未使用Text Mask时,用户输入体验存在明显痛点:

  • 电话号码需手动添加分隔符
  • 数字输入缺乏视觉分组
  • 格式错误需提交后才能发现

集成后效果: 动态掩码效果

性能优化建议

  1. 掩码缓存
    使用useMemo缓存静态掩码,避免重复创建:

    const mask = useMemo(() => createNumberMask({ prefix: '$' }), []);
    
  2. 输入防抖
    对高频输入场景(如实时搜索)添加防抖处理:

    const debouncedChange = useCallback(
      debounce((text) => { /* 格式化逻辑 */ }, 100),
      [mask]
    );
    
  3. 条件渲染
    复杂掩码(如信用卡号)可延迟初始化,优先渲染基础输入框。

常见问题解决方案

光标跳转异常

当格式化导致输入长度变化时,需显式控制光标位置:

const [selection, setSelection] = useState({ start: 0, end: 0 });

const handleChange = (text) => {
  const { conformedValue, meta } = conformToMask(text, mask);
  setValue(conformedValue);
  
  if (!meta.someCharsRejected) {
    setSelection({ start: conformedValue.length, end: conformedValue.length });
  }
};

Android键盘兼容性

部分Android键盘可能导致事件延迟,建议添加输入类型限制:

<TextInput 
  keyboardType="phone-pad" 
  returnKeyType="done"
  {...props} 
/>

扩展应用场景

  1. 表单验证集成
    结合React Hook Form实现格式化+验证一体化:

    const { register, watch } = useForm();
    const formattedValue = watch('phone');
    // 验证逻辑...
    
  2. 多语言适配
    根据设备语言动态切换掩码格式:

    const localeMask = i18n.locale === 'en-US' ? usPhoneMask : cnPhoneMask;
    
  3. 自定义掩码规则
    通过正则表达式创建业务专属格式:

    const licenseMask = [/[A-Z]/, /[A-Z]/, /\d/, /\d/, /[A-Z]/, /\d/]; // 如AB12C3
    

完整实现可参考react/example/app.js的Web版本逻辑,移动端需注意替换DOM相关API为React Native等价实现。通过这套方案,开发者可在保持代码一致性的前提下,为移动应用提供专业级输入格式化体验。

【免费下载链接】text-mask Input mask for React, Angular, Ember, Vue, & plain JavaScript 【免费下载链接】text-mask 项目地址: https://gitcode.com/gh_mirrors/te/text-mask

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐