I'm building this To Do App which has multiple heading and topics. The state of the To do's is following:
{ Big Heading: "Todo List", topics: [ { Heading: "What to do today", Topics: [ { topic: "Mow the lawn", desc: "Before mowing the lawn move the kids pool"} ... ] } ... ] }
I map the topics:
{Topic.topics.map((topics, j) =>
<tr key={`${index}-${j}`}>
<td>
<textarea
type="text"
id={`topic${index}`}
name="topic"
defaultValue={topic.topic}
onChange={event => handleInputChange(index, event, j)}
></textarea>
</td>
<td>
<textarea
style={{width: "100%"}}
type="text"
id={`desc${index}`}
name="desc"
defaultValue={topic.desc}
onChange={event => handleInputChange(index, event, j)}
></textarea>
<Button variant="danger" size="sm" onClick={() => deleteTopic(index, j)}>-</Button>
<AddButton array={inputFields[index].topics} index={index} j={j} />
</td>
</tr>
)}
I'm trying to remove some of the Topics with buttons very next to the topic on function deleteTopic(index, j) Index comes from higher map for the Topic and Heading.
const deleteTopic = (index, j) => {
const values = [...inputFields]
values[index].topics.splice(j, 1)
setInputFields(values)
}
THE PROBLEM When using function deleteTopic it sets inputFields with correct State ( removing the correct topic from correct array with index and j). But react Render deletes the last topic that can be seen even though it still remains in the state and the one that was deleted from the state is still shown on the To Do list.
If I change the <tr key="1"> IT WORKS! But then every row has same key and textarea unfocuses onChange. If someone more educated would know why it works when all keys are same but when theyr not it doesnt work.
keyis based on the array index, and the array values change indexes when you delete an item (besides the last item). This causes react to update and unmount the wrong elements