6

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

0

3 Answers 3

5

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

Sign up to request clarification or add additional context in comments.

4 Comments

what if the input passed in is name not price?
@tsecheukfung01 Ah, good catch. Guess OP will need to handle the numerical fields separately.
It's work, however, there is more input field like string, then problem arise NaN, ```
@MamunurRashid You are exactly right. I amended my solution to use a "reducer" type pattern to check the input's type attribute and handle the state update accordingly. Apologies for initially misunderstanding your full issue.
0

Have you tried changing it that way?

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

1 Comment

if there is no input, there is a NaN problem again
0

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,
});

4 Comments

Input is not an only string, there is more input like string, then NaN is a problem
Updated the answer. Btw, just see your comment in below answer. When creating product, some checking can be done. Eg. can prevent there should be some input
While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn and eventually apply that knowledge to their own code. You are also likely to have positive-feedback/upvotes from users, when the code is explained.
@AmitVerma Good point, updated the answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.