Home > OS >  Why is my value not being updated? useState
Why is my value not being updated? useState

Time:08-25

I'm using useState hook to update the values of my inputs inside a form. This is the object I'm using in my useState hook:

const [values, setValues ] = useState({
    name: '',
    lastname: '',
    email: '',
    confirmEmail: '',
    message: ''
  });

Then I have an array with the inputs and there type id and other fields:

const inputs = [
    {
      id: Math.random(),
      name: 'name',
      type: 'text',
      placeholder: 'Name'
    },
    {
      id: Math.random(),
      name: 'lastname',
      type: 'text',
      placeholder: 'Last Name'
    },
    {
      id: Math.random(),
      name: 'email',
      type: 'email',
      placeholder: 'Email'
    },
    {
      id: Math.random(),
      name: 'confirmEmail',
      type: 'email',
      placeholder: 'Confirm Email'
    }
]

I have the following handleChange function to update the state of my values which replaces the name property of my object with the value I enter in the input.

const handleChange = (e) => {
    setValues({...values, [e.target.name]: e.target.value}) 
    console.log(values)
  }

This is my complete component so that you can see what I'm rendering:

ContactForm.js:

import React, {useState} from 'react'
import SubmitBtn from '../atoms/SubmitBtn';
import FormInput from '../molecules/FormInput'

const ContactForm = () => {

  const [values, setValues ] = useState({
    name: '',
    lastname: '',
    email: '',
    confirmEmail: '',
    message: ''
  });

  const inputs = [
    {
      id: Math.random(),
      name: 'name',
      type: 'text',
      placeholder: 'Name'
    },
    {
      id: Math.random(),
      name: 'lastname',
      type: 'text',
      placeholder: 'Last Name'
    },
    {
      id: Math.random(),
      name: 'email',
      type: 'email',
      placeholder: 'Email'
    },
    {
      id: Math.random(),
      name: 'confirmEmail',
      type: 'email',
      placeholder: 'Confirm Email'
    },
    {
      id: Math.random(),
      name: 'message',
      type: 'text',
      placeholder: 'Message'
    }
  ]

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Hello world');
  }

  const onChange= (e) => {
    setValues({...values, [e.target.name]: e.target.value}) 
    console.log(values)
  }    

  return (
    <form className='contactForm' onSubmit={handleSubmit}>
      {inputs.map((input)=>(
        <FormInput 
        key={input.id} 
        {...input} 
        value={values[inputs.name]} 
        onChange={onChange}
        />
      ))}
      <SubmitBtn/>         
    </form>
  )
}

export default ContactForm

FormInput.js:

import React from 'react'
import './FormInput.css';
import { Input } from '../atoms/Input';

const FormInput = (props) => {

  const { id, onChange, ...inputProps } = props;

  return (
    <div className='formInput'>
        {/* <label htmlFor="">Username</label> */}
        <Input {...inputProps} onChange={onChange}/>
    </div>
  )
}

export default FormInput

Input.js:

import React from 'react'

export const Input = (props) => {

    const { id, onChange, ...inputProps } = props;

  return (
    <input {...inputProps} onChange={onchange} />
  )
}

I tried making a console.log(values) to see the values as they change but it just shows it one time in the console and all the values are empty. I tried doing a console.log inside the handleChange function as well as outside.

Object { name: "", lastname: "", email: "", confirmEmail: "", message: "" }

CodePudding user response:

I found two things to fix here:

a. In Input.js ,

 const { id, onChange, ...inputProps } = props;

return (
    <input {...inputProps} onChange={onChange} />

Here, the onChange in input tag was onchange instead of onChange.

b. In ContactForm.js,

return (
    <form className='contactForm' onSubmit={handleSubmit}>
      {inputs.map((input)=>(
        <FormInput 
        key={input.id} 
        {...input} 
        value={values[input.name]} 
        onChange={onChange}
        />
      ))}
      <SubmitBtn/>         
    </form>
  )
}

Here, the value in FormInput was value={values[inputs.name] instead of value={values[input.name]}. Note the 's' in input.

Copy these codes, it should work.

CodePudding user response:

setState is async - you can't just console.log the updated version right after you fire the setter because execution of the setter is put on the call stack after the console log. Try a useEffect to console log every time values changes to see if a change is being triggered.

useEffect(() => console.log(values), [values])

Or just render the values to the bottom of your form temporarily for debugging purposes and you should see them update when a new value is added.

CodePudding user response:

You should use console.log(values) outside of the handleChange function.

  • Related