0

Trying to log the values of name, day and dob elements stored in dataEdited as object.Two of the elements display Undefined with just one displaying the correct value. Here is the code

/* two-way state binding */ dataChange(event){ const target = event.target; const value = target.value; //gets value of the textbox const name = target.name; this.setState({ dataEdited: {[name]: value} }); } handleUpdate(event){ event.preventDefault(); const {name,day,dob} = this.state.dataEdited; console.log(name, day, dob); /* this.setState({ toggle: false }) */ } 

State

this.state = { name: '', day: '', dob: '', items : [], currentItem: {}, dataEdited: {}, toggle: false, loading: false } 

Render

<form onSubmit={this.handleUpdate}> <input className="" name="name" onChange={this.dataChange} defaultValue={this.state.currentItem.name} placeholder= "Celebrant's Name" ref={name => this.name = name} required /> <input className="" type="number" name="day" min="1" max="31" ref={day => this.day = day} onChange={this.dataChange} defaultValue={this.state.currentItem.day} placeholder= "day" /> <input className="" name="dob" type="month" onChange={this.dataChange} defaultValue={this.state.currentItem.dob} /> <button type="submit">update</button> <button onClick={this.handleEditCancel}>cancel</button> </form> 

This is the result on the console

undefined undefined "2020-08" 

I don't understand how this is possible, can I get an explanation. Also, how can I fix this?

5
  • what do you get when you log this.state.dataEdited to the console Commented Apr 2, 2020 at 9:20
  • Show the render function code Commented Apr 2, 2020 at 9:22
  • as mentioned in the question i got Undefined Undefined "2020-08" Commented Apr 2, 2020 at 9:23
  • can you share this.setState code Commented Apr 2, 2020 at 9:26
  • 1
    setState({ dataEdited: {[name]: value} }). You're setting dataEdited as an object that only has a single property. React only performs a shallow merge (Object.assign) when setting state, so if you redefine a state value that is an object, you have to spread the old value into the new one. Commented Apr 2, 2020 at 9:32

3 Answers 3

3

When you execute this.setState({ dataEdited: {[name]: value} }); you overwrite the other values in the object assigned to dataEdited.

You should change that to this.setState({ dataEdited: { ...this.state.dataEdited, [name]: value} }); to preserve the previous values inside this.state.dataEdited

UPDATE (Thanks @JMadelaine): You should use this.setState(prev => ({ dataEdited: { ...prev.dataEdited, [name]: value}})); to ensure that no concurrent state changes affects the setState()

More info: https://stackoverflow.com/a/50837784/10201813

Sign up to request clarification or add additional context in comments.

1 Comment

You should pass a function since your new state value depends on the previous value: this.setState(prev => ({ dataEdited: { ...prev.dataEdited, [name]: value}}));
2

Problem

you are overwriting the same dataEdited variable over and over when you call this.setState({ dataEdited: {[name]: value} }); Thus only the last changed data will be present inside dataEdited

Solution

Seperately save the data or change setState function appropriately

Comments

0

You are overwriting the state variable dataEdited everytime you call

this.setState({ dataEdited: {[name]: value} }); 

so you want to change spread the object dataEdited and the state After that add or change the name,dob or day

 this.setState({ ...this.state, dataEdited: { ...this.state.dataEdited, [name]: value } }); 

CodeSandbox here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.