Answer the question
In order to leave comments, you need to log in
Why is data changing in two states at the same time?
Good afternoon! I am trying to make a table with editable fields. The idea is that when you click on the save button, the data from the input should be saved in the table, and when you click on the cancel button, the data in the table should not change. I have a problem with the contacts and contactsInput states. The first state is needed in order to display data in a table. The second is for the value field in . When data is written to one state, it is written to another state. Although, as far as I understand, they do not have common links. Thanks in advance!
import React, {Fragment, useState} from 'react'
export default function ContentTable() {
const data = [
{
"id": 1,
"fullName": "Jenny Chan",
"address": "3 waterfoot road",
"phoneNumber": "333-962-7516",
"email": "[email protected]"
},
{
"id": 2,
"fullName": "Jessica warren",
"address": "4 tall town",
"phoneNumber": "011-211-7516",
"email": "[email protected]"
},
{
"id": 3,
"fullName": "Tony Frank",
"address": "11 lesly road",
"phoneNumber": "788-962-7516",
"email": "[email protected]"
},
{
"id": 4,
"fullName": "Jeremy Clark",
"address": "333 miltown manor",
"phoneNumber": "011-962-111",
"email": "[email protected]"
},
{
"id": 5,
"fullName": "Raymond Edwards",
"address": "99 blue acres",
"phoneNumber": "3231-962-7516",
"email": "[email protected]"
}
]
const [contacts, setContacts] = useState([...data])
const [contactsInput, setContactsInput] = useState([...data])
const [checkId, setCheckId] = useState(null)
const handleChange = (index) => (
(event) => {
const {name, value} = event.target
const contactsInputCopy = [...contactsInput]
contactsInputCopy[index][name] = value
console.log(index, name)
console.log(contactsInputCopy[index][name])
console.log(contacts[index][name])
setContactsInput(contactsInputCopy)
}
)
const handleSave = () => {
setContacts([...contactsInput])
setCheckId(null)
}
const handleCancel = (event) => {
setCheckId(null)
}
return (
<div className="tableContainer">
<table>
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Phone number</th>
<th>email</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{contacts.map((contact, index) => (
<Fragment key={`key:${index}`}>
{checkId === contact.id ? (
<tr>
<td>
<input type="text" name="fullName" value={contactsInput[index].fullName} onChange={handleChange(index)}/>
</td>
<td>
<input type="text" name="address" value={contactsInput[index].address} onChange={handleChange(index)}/>
</td>
<td>
<input type="text" name="phoneNumber" value={contactsInput[index].phoneNumber} onChange={handleChange(index)}/>
</td>
<td>
<input type="text" name="email" value={contactsInput[index].email} onChange={handleChange(index)}/>
</td>
<td>
<input type="button" value="Save" onClick={handleSave}/>
<input type="button" value="Cancel" onClick={handleCancel}/>
</td>
</tr>
) : (
<tr>
<td>{contact.fullName}</td>
<td>{contact.address}</td>
<td>{contact.phoneNumber}</td>
<td>{contact.email}</td>
<td>
<input type="button" value="Edit" onClick={() => setCheckId(contact.id)}/>
</td>
</tr>
)}
</Fragment>
))}
</tbody>
</table>
</div>
)
}
Answer the question
In order to leave comments, you need to log in
const copyArray = (array = []) => JSON.parse(JSON.stringify(array));
const [contacts, setContacts] = useState(copyArray(data));
const [contactsInput, setContactsInput] = useState(copyArray(data));
Inside handleChange change the line a little:
contactsInputCopy[index] = { ...contactsInputCopy[index], [name]: value }
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question