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.