React component doesn't append newly added items to the list
I have a react component that prints out a list of items from an array of objects. Each object can either be a newly created one, or it can be the same object but with some of its properties updated.
Updating an existing object occurs without problems, but when a new object is received, the length of the array increases by 1, and all elements become duplicates of the newly added object.
Here is the react component:
{quests.map(quest => (
<div>
<div className={styles.questTitle}>{quest.description.title}</div>
<ul className={styles.questsList}>
{quest.description.steps.map(step => (
<li key={quest.id} className={styles.questStep}>{`${quest.status}/2 ${step}`}</li>
))}
</ul>
</div>
))}
Here is how it gets updated:
@action
setQuests(quest: QuestFuncReturnValue) {
// If the quest doesn't exist, append it to the quests list, else update it
const questExists = this.quests.find(oldQuest => oldQuest.id === quest.id);
if (!questExists) {
this.quests = [...this.quests, quest];
return;
}
const updatedQuests = this.quests.map(oldQuest => (quest.id === quest.id ? quest : oldQuest));
this.quests = updatedQuests;
console.log(this.quests);
}
I'm using Mobx for the state: Here is the initial value of the array:
@observable.ref quests: QuestFuncReturnValue[] = [];
Solution 1:
I am not sure if this is the problem, but there should be "key" everywhere you use rendering list.
See key={quest.id} and key={step}
{quests.map(quest => (
<div key={quest.id}>
<div className={styles.questTitle}>{quest.description.title}</div>
<ul className={styles.questsList}>
{quest.description.steps.map(step => (
<li key={step} className={styles.questStep}>{`${quest.status}/2 ${step}`}</li>
))}
</ul>
</div>
))}