Search code examples
reactjssetstatecomplextype

React Form single handleChange function with multiple inputs and setState to complex object


I have a form inside a React component that has several inputs, representing properties of an object, defined in the component's state. I would like to make a POST request to my REST API by which I want to create an entity, by passing the filled in object from this.state, which in turn is modified by the form inputs. I am unable to figure out how to use single handleChange() method to update the state on an onChange event of all the fields. I refereed to articles describing this problem but without complex types. I even tried to implement the dynamic key name by using [event.target.name] and adding name attribute to all of my form inputs but with no result.

Here is my code. Component constructor and state:

class IngredientForm extends React.Component {
constructor(props) {
        super(props);
        this.apiService = new apiService();
        this.state = {
            ingredient: {
                id: "",
                name: "",
                dateAdded: "",
            }
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }
}

handleChange and handleSubmit methods:

    handleChange(event) {
        const ingredient = this.state.ingredient;
        ingredient[event.target.name] = event.target.value;
        this.setState({ ingredient: ingredient });
    }

handleSubmit(event) {
        //Fetch code goes here
        let response =  this.apiService.postDataAsync("https://localhost:5001/api/ingredients",this.state.ingredient);
        this.setState({ingredient:{id: response.id, dateAdded: response.dateAdded}});
        event.preventDefault();
    }

And this is the code of the form:

<form onSubmit={this.handleSubmit}>
    <label>
        Name
    </label>
    <input
        type="text"
        name="name"
        value={this.state.ingredient.name}
        onChange={this.handleChange}
        required
    />
        <label>Date added</label>
        <input
            type="date"
            name="dateAdded"
            value={this.state.ingredient.dateAdded}
            onChange={this.handleChange}

        />

    <button type="submit" value="Submit">
        Save
    </button>

</form>

I will be glad to receive your help. I tried to find a similar topic in the forum beforehand, but without success, everyone discussed the situation with primitive types in the state.


Solution

  • hey there the problem is in your set state can you tru this?

    handleChange(event) {
        const {name, value} = event.target;
        this.setState({ 
            ingredient: {
                ...this.state.ingredient,
                [name]: value
            } 
        });
    }