React js update form value using useState

Viewed 2018

I have a React functional component, a form accepting information for events. I need to send the filled in form info using a POST request. My formData state is not updating, I have tried different onChange functions to try and get this to work. Any ideas where I am going wrong?

`

import styled from 'styled-components';

import axios from 'axios';

import Input from './Input';

import react, {useState, useEffect} from "react";

import DateTimePicker from 'react-datetime-picker';

import TimePicker from "react-time-picker";

import DatePicker from "react-date-picker";

const url = 'http://localhost:5000/events/create'

const EventForm = (props)=> {
const [dateValue, onChangeDate] = useState(new Date());

const [timeValue, onChangeTime] = useState();

const [formData, setFormData] = useState({
    firstName: '',
    lastName: '',
    contactEmail: '',
    eventTitle: '',
    eventDescription: '', 
})

function onChange (e) {
    let name = e.target.name ;
    let value = e.target.value;
    let formObj = { ...formData };
    setFormData({ ...formData, [name]: value });
    console.log(formData)
}
const body = {
    firstName: formData.firstName,
    lastName: formData.lastName,
    contactEmail: formData.contactEmail,
    eventTitle: formData.eventTitle,
    eventDescription: formData.eventDescription,
    eventDate: dateValue,
    eventTime: timeValue,
}
const postFormData = async (e) => {
    console.log(formData)
    e.preventDefault()
    await axios({
        method: 'post',
        url: url,
        data: body,
     })
    .then((response) => {
        console.log(response)
    })
    .catch(error => console.log(`Error: ${error}`));
}

// const postFormData = async (e) => {
//     e.preventDefault()
//     let newEvent = await fetch("http://localhost:5000/events/create",
//         {
//             method: "POST",
//             headers: {
//                 'Content-Type': 'application/json',
//                 'Accept': 'application/json'
//             },
//             body: JSON.stringify(body)
//         });
//         newEvent = await newEvent.json();
//         console.log(newEvent);
// }
    useEffect(() => {
        return () => {
        console.log(formData.firstName)
        }
    })

  return (
    <form onSubmit={props.onSubmit}>
    <>
    {/* <DateTimePicker onChange={onChange} value={value} minDate={new Date()}/> */}
    <StyledForm onSubmit={postFormData}>
        <label>
            First Name
        </label>
        <Input 
            name={"firstName"} 
            placeholder={"First Name"} 
            type={"text"}
            value={formData.firstName}
            onChange={(e) => setFormData({ ...formData, firstName: e.target.value})}
        />
        <label>
            Last Name
        </label>
        <Input 
            name={"lastName"} 
            placeholder={"Last Name"} 
            type={"text"}
            onChange={onChange}
        />
        <label>
            Contact Email
        </label>
        <Input 
            name={"contactEmail"} 
            placeholder={"Email"} 
            type={"email"} 
            onChange={onChange}
        />
        <label>
            Event Date
        </label>
        <DatePicker onChange={onChangeDate} value={dateValue}/>
        <label>
            Event Time
        </label>
        <TimePicker onChange={onChangeTime} value={timeValue} />
        <label>
            Event Description
        </label>
        <Input 
            name={"eventTitle"} 
            placeholder={"Event Title"} 
            type={"text"}
            onChange={onChange}
        />
        <label>
            Event Description
        </label>
        <Input 
            name={"eventDescription"} 
            placeholder={"Event Description"} 
            type={"text"}
            width={"300px"}
            height={"300px"}
            onChange={onChange}
        />


        <Input 
            name={"submit"} 
            type={"submit"} 
            value={"Create"} 
        />       
    </form>
    </>
  );

}

export default EventForm;`

1 Answers

The formData state variable will not update immediately, your console.log will always print the original value before the update. Also when the next state is computed using the previous state like in your example, you should use the functional update version of setState:

const [formData, setFormData] = useState({
    firstName: '',
    lastName: '',
    contactEmail: '',
    eventTitle: '',
    eventDescription: '', 
})

function onChange (e) {
    let name = e.target.name;
    let value = e.target.value;
    setFormData((currentFormData) => {
      const nextFormData = {
        ...currentFormData,
        [name]: value,
      })
      console.log(nextFormData)
      return nextFormData;
    );
}
Related