灏天阁

React 项目中封装 Input 输入框只能输入数字的 hooks 方法

· Yin灏

这次还是使用React来实现一个只能输入数字的Input输入框。首先还是先来创建一个基础的Input组件,如下:

import React, { useState } from "react";

/**
 * 输入数字组件
 * @constructor
 */
const InputNumber = () => {
  const [val, setVal] = useState("");

  /**
   * 输入框onChange
   * @param e
   */
  const onChangeInput = (e: any) => {
    setVal(e.target.value);
  };

  return (
    <>
      <input
        type="text"
        value={val}
        onChange={(e) => onChangeInput(e)}
        style={{ height: 24 }}
      />
    </>
  );
};

这样你就可以得到一个没有任何输入限制的输入框组件了。

下面就来加上限制:只能输入数字字符

有经验的小伙伴瞬间就能想到只要在setVal前加上移除非数字字符的方法,然后再setVal即可。如下:

const InputNumber = () => {
  const [val, setVal] = useState("");

  /**
   * 输入框onChange
   * @param e
   */
  const onChangeInput = (e: any) => {
    const { value } = e.target || {};
    let val = value.replace(/[^\d]/g, "");
    setVal(val);
  };

  return (
    <>
      <input
        type="text"
        value={val}
        onChange={(e) => onChangeInput(e)}
        style={{ height: 24 }}
      />
    </>
  );
};

从上述代码可以看到,移除非数字字符的方法是使用了replace方法,然后通过正则/[^\d]/g来查找非数字字符,找到就将其替换为空字符串,这样就能将非数字的字符给移除掉,最后就能返回一个只有数字字符的字符串了。

到这里,简单的实现一个只能输入数字的输入框组件就编写完成了,但是这不是我们的最终目的。为了可以在任何的Input或输入框组件上使用,我们将试着将其封装为hook,方便项目中进行引用。

那下面就来开始这篇文章的主题,将上述的代码改造一下就可得到一个只能输入数字的hook,直接上代码,如下 →

import React, { useState } from "react";

// 输入数字hooks
const useInputNumberState = (defaultVal = ""): [string, (e: any) => void] => {
  const [val, setVal] = useState(defaultVal);

  const handleChange = (e: any) => {
    const { value } = e.target || {};
    let val = value.replace(/[^\d]/g, "");
    setVal(val);
  };

  return [val, handleChange];
};

/**
 * 输入数字组件
 * @constructor
 */
const InputNumber = () => {
  const [val, setVal] = useInputNumberState("");

  return (
    <>
      <input
        type="text"
        value={val}
        onChange={(e) => setVal(e)}
        style={{ height: 24 }}
      />
    </>
  );
};

export default InputNumber;

从上述代码可以看到,将之前的onChangeInput的方法结合useState封装了一个useInputNumberStatehooks,这样在页面使用的时候就不需要再编写onChangeInput里面的逻辑,直接在页面顶部使用useInputNumberState这个hooks就能实现只能输入数字的逻辑了。

但是这个useInputNumberState方法还存在缺陷,那就是如果用户输入的数字前面有0的情况,就不是一个合法的整数,到时还需要在引用的页面再去移除数字前面的0就显得多此一举,所以最好就在useInputNumberState方法就把数字前面是0的情况给处理掉,让其直接返回的值就是一个合法的整数。

说干就干,接着往下看 →

// 输入数字hooks
const useInputNumberState = (defaultVal = ""): [string, (e: any) => void] => {
  // 移除字符前面的零
  const removeZeros = (str: string) => {
    return str.replace(/^0+/, "");
  };

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

  const handleChange = (e: any) => {
    const { value } = e.target || {};
    let val = value.replace(/[^\d]/g, "");
    setNumVal(removeZeros(val));
  };

  return [numVal, handleChange];
};

从上述代码可以看到,只需在useInputNumberState方法里面增加一个移除字符串前面0removeZeros()方法即可达到效果。

上述的代码示例中,是将useInputNumberState方法放置在引用页面的顶部的,其实实际项目中,应该把useInputNumberState方法定义在一个外部的js文件中,然后再进行引用,这样就能让封装的useInputNumberState方法能被其他协作的人进行调用,从而从根本解决不再重复编码的问题了。

最后,实现Input输入框只能输入数字的需求并不复杂,只需在onChange的时候对value进行处理,从而就能得到只含数字的字符串了。希望可以通过这个只能输入数字的hooks的思路,能帮助到你在实际工作中将其他常见的可复用的方法进行封装并能解决编写过多的重复代码的问题。

- Book Lists -