终究没有人在意一家民营企业的生死

去泰国看了一场“成人秀”,画面尴尬到让人窒息.....

【少儿禁】马建《亮出你的舌苔或空空荡荡》

网友建议:远离举报者李X夫!

司马南|脱口秀算什么?

生成图片,分享到微信朋友圈

自由微信安卓APP发布,立即下载! | 提交文章网址
查看原文

React 实现只能输入数字的 input

前端西瓜哥 前端西瓜哥 2023-01-28

大家好,我是前端西瓜哥。

今天我们用 React 来实现一个只能输入数字的 input。

先写一个基础的 input 受控组件。

function Form() {
  const [numVal, setNumVal] = useState('');

  return (
    <input type="text" value={numVal} onChange={e => setNumVal(e.target.value)} />
  );
}

上面这种写法没有做任何限制,你可以在 input 元素上输入任何内容。

只能输入数字字符

现在我们要加入限制:只能输入数字字符

很容易想到的做法是在 setNumVal 上封装多一层方法。这个方法会将 e.target.value 中非数字字符的部分移除,然后再传入到 setNumVal

function Form() {
  const [numVal, setNumVal] = useState('');

  const handleChange = (val: string) => {
    val = val.replace(/[^\d]/g'');
    setNumVal(val);
  }

  return (
    <input type="text" value={numVal} onChange={e => handleChange(e.target.value)} />
  );
}

这里用了 string.prototype.replace 方法,/[^\d]/g 表示找非数字字符,g 表示多次查找,如果不带上,replace 只会替换第一个匹配字符串。

找到它们并将它们替换为空字符串,也就是移除掉,最后返回一个只有数字字符的字符串。

为了可以在任何的 input 或输入框组件上使用,我们不妨将其封装为 hook。

const useNumStrState = (defaultVal = ''): [string, (val: string) => void] => {
  const [numVal, setNumVal] = useState(defaultVal);

  const handleChange = (val: string) => {
    val = val.replace(/[^\d]/g'');
    setNumVal(val);
  }

  return [numVal, handleChange];
}

// 使用
function Form() {
  const [numVal, setNumVal] = useNumStrState('');

  return (
    <input type="text" value={numVal} onChange={e => setNumVal(e.target.value)} />
  );
}

这样,一个有着基础能力的只能输入数字的 input 就完成了。

增强:移除前导 0 版本

下面再实现一个去掉前导 0 的版本,让用户只能输入合法的整数。

const useNumStrState = (defaultVal = ''): [string, (val: string) => void] => {
  const removeLeadingZeros = (s: string) => {
    const oldLen = s.length;
    s = s.replace(/^0+/''); // 移除前导零
    // 全为 0 的情况,留一个 0
    if (s.length === 0 && oldLen > 0) {
      s = '0';
    }
    return s;
  }

  defaultVal = removeLeadingZeros(defaultVal);
  const [numVal, setNumVal] = useState(defaultVal);

  const handleChange = (val: string) => {
    val = val.replace(/[^\d]/g'');
    val = removeLeadingZeros(val);
    setNumVal(val);
  }

  return [numVal, handleChange];
}

同样也是用 replace 方法,/^0+/ 的意思是匹配从字符串首位开始的连续尽可能多的 0,然后将它们替换为为空字符串。

这里有一种特殊的情况,就是全是 0 的字符串,比如 0000,这时候需要保留一个 0。

结尾

让 input 只能输入数字并不复杂,只需要在 onChange 的时候将 e.target.value 进行处理,得到只含数字的字符串,再用它来修改状态就好了。

另外也不得不说 React Hook 是真的牛逼,让我们可以做到比组件更细粒度的复用逻辑封装。


文章有问题?点此查看未经处理的缓存