Updating Input type number in React Form

Viewed 1329

I am trying to update the input value. It's working fine, it's updating its value. However, there is a problem, when it's updated its value, it's converting to string from number. I have already tried with Number, parseInt, it does not work. it always converts to string.

import React from 'react';
import useForm from '../lib/useForm';

const CreateProduct = () => {
  const { input, handleChange } = useForm({
    name: 'mama',
    price: 0,
  });
  return (
    <form>
      <label htmlFor="price">
        Price
        <input
          type="number"
          id="price"
          name="price"
          placeholder="Price"
          value={parseInt(input.price)}
          onChange={handleChange}
        />
      </label>
    </form>
  );
};

export default CreateProduct;

and here in the custom function:

import * as React from 'react';

export default function useForm(initialValue = {}) {
  const [input, setInput] = React.useState(initialValue);

  function handleChange(event) {
    const { name, value } = event.target;
    setInput({
      ...input,
      [name]: value,
    });
  }
  return {
    input,
    handleChange,
  };
}

and here is the initial state: enter image description here

and here is the updated state with the number gotcha enter image description here

3 Answers

Issue

Inputs deal only in strings. If you want the value to be anything other than you should convert it when passing to the handler, or in the handler itself.

Solution

Convert the value back to a number when processing in handler

function handleChange(event) {
  const { name, type, value } = event.target;

  setInput(input => {
    const nextInput = {...input}

    switch(type) {
      case 'number':
        nextInput[name] = Number(value);
        break;

      // handle other input type cases

      default:
        nextInput[name] = value;
    }
    return nextInput;
  });
}

Edit updating-input-type-number-in-react-form

This check whether name 's type is number or not. When it is number, parse it to Number type to prevent it be converted to string. If not, just update the input by what it is originally pass in.

setInput({
      ...input,
      [name]: typeof name === 'number' ? Number(value) : value,
});

Have you tried changing it that way?

   setInput({
      ...input,
      [name]: name === "price" ? parseInt(value) : value,
});
Related