ReactJS: one digit input can end up with multiple '0's

Viewed 266

Basically, I want a little box with only one digit, it "works" fine until you try to put multiple '0', then in the box, multiple 0000 persist.

multiple 0 console logs

The code

const InputBox = () => {
  const [value, setValue] = useState(0);

  const handleChange = el => {
    const newValue = el.target.value;
    console.log(newValue);
    const lastNumber = parseInt(
      newValue.toString().slice(-1),
    );
    console.log(lastNumber);
    setValue(lastNumber);
  };

  return (
    <input
      type='number'
      pattern='[0-9]'
      min='0'
      max='9'
      id='numberInput'
      maxLength={1}
      minLength={1}
      value={value}
      onInput={handleChange}
      // onChange={handleChange}
      className='inputBox'
    />
  );
};

export default InputBox;

How to make it so I have only one digit at any time?

3 Answers
  • Don't need to parse to int or to string, just slice and set value.
  • minLength and maxLength doesn't work in <input type="number">.
const InputBox = () => {
  const [value, setValue] = useState(0);

  const handleChange = (el) => {
    let newValue = el.target.value;
    if (newValue.length > 1) {
      newValue = newValue.slice(0, 1);
    }
    setValue(newValue);
  };

  return (
    <input
      type="number"
      pattern="[0-9]"
      min="0"
      max="9"
      id="numberInput"
      value={value}
      onInput={handleChange}
      className="inputBox"
    />
  );
};

This could work out

const handleChange = el => {
    const newValue = el.target.value;
    const lastNumber = newValue.replace(/[^0-9]/g,'')
    setValue(lastNumber);
  };

  return (
    <input
      type="text" maxlength="1" 
      value={value}
      onInput={handleChange}
    />
  );

If you don't mind the type coercion to string of your state (you can always Number(value) when you need a number type for computations) then you can simply slice off the last char of the value and if it ends up being a falsey ('', 0, null, undefined, NaN) value fallback to 0 to allow coercion back to "0" when assigning to the value prop of the input. Also, the minLength|maxLength|pattern attributes only work when doing field validation in a form.

const handleChange = (el) => {
  const { value } = el.target;
  setValue(value.slice(-1) || 0);
};

Edit zen-tree-p9yt1

const InputBox = () => {
  const [value, setValue] = useState(0);

  const handleChange = (el) => {
    const { value } = el.target;
    setValue(value.slice(-1) || 0);
  };

  return (
    <input
      type="number"
      min="0"
      max="9"
      id="numberInput"
      value={value}
      onChange={handleChange}
      className="inputBox"
    />
  );
};
Related