Home > Software design >  React input validation with onChange
React input validation with onChange

Time:07-13

I have a numeric input, which I want to validate with an onChange, but when said input is cleared, react throws ReferenceError: value is not defined which is understandable - it has nothing to validate.

I'm using this approach [Answer]

I'm using functional components and here is my code snippet:

   const [formData, setFormData] = React.useState({
        userTeamChosen: "",
        eventNumber: 0,
        value: 0,
        ethValue: 0})

    function handleNumeric(event) {
        const { name, checkedValue, min, max } = event.target
        value = Math.max(Number(min), Math.min(Number(max), Number(value)));
        setFormData(prevFormData => {
            return {...prevFormData,[name]: checkedValue}})}

    <input
        type="number"
        name="value"
        value={formData.value}
        onChange={handleNumeric}
        min="5"
        max="10000000"/>

How should I change my validation, to keep in onChange, but without erroring, when the input is empty? Thanks in advance!

CodePudding user response:

There is no a checkedValue property in the number input element, Use valueAsNumber or value instead.

function handleNumeric(event) {
    const { name, valueAsNumber, min, max } = event.target
    const result = Math.max( min, Math.min( max, !Number.isNaN(valueAsNumber) ? valueAsNumber :  min));
    setFormData(prevFormData => {
        return {...prevFormData,[name]: result}})}

CodePudding user response:

Looks like you were very close to solving this one yourself :D

The only errors I noticed were the value variables not being declared or defined anywhere, to solve this I just added formData so that react would know that it's the formData's value being used and not some random value

function handleNumeric(event) {
    const { name, checkedValue, min, max } = event.target
    formData.value = Math.max(Number(min), Math.min(Number(max), Number(formData.value)));
    setFormData(prevFormData => {
        return {...prevFormData,[name]: checkedValue}})}

CodePudding user response:

You should call

 function handleNumeric(event) {
        const { name, checkedValue, min, max } = event.target
        formData.value = Math.max(Number(min), Math.min(Number(max), Number(formData.value)));
        setFormData(prevFormData => {
            return {...prevFormData,[name]: checkedValue}})}

CodePudding user response:

A number input is considered valid when empty. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number. So if you empty the input and try to check valueAsNumber it will return NaN. You can check for this case using isNaN():

    function handleNumeric(event) {
        const { name, checkedValue, min, max } = event.target
        if (isNaN(checkedValue)) checkedValue = 0;
        value = Math.max(Number(min), Math.min(Number(max), Number(checkedValue)));
        setFormData(prevFormData => {
            return {...prevFormData,[name]: checkedValue}})}

Other than that, your solution should be working fine in all other cases. Placing a required attribute on the number input may help as well since it will ask the browser to prevent users from emptying the input.

  • Related