I am using React and have the following object:
const [records, setRecords] = useState(
[
{id: 1, correct: false},
{id: 2, correct: false},
{id: 3, correct: false},
{id: 4, correct: false},
{id: 5, correct: false}
]);
To update the object I have the following:
const onCorrectAnswerHandler = (id, correct) => {
setRecords(
records.map((record) => {
if (record.id === id) {
return { id: id, correct: true };
} else {
return record;
}
})
);
}
Here’s the problem:
I want to run another function called isComplete after it but within the Handler function, that uses the changed records object, but it appears to use the original unchanged ‘records’ object (which console.log confirms).
e.g.
const onCorrectAnswerHandler = (id, correct) => {
setRecords(
records.map((record) => {
if (record.id === id) {
return { id: id, correct: true };
} else {
return record;
}
})
);
isComplete(records);
}
Console.log(records) confirms this. Why does it not use the updated records since the isComplete function runs after the update, and how can I get it to do this?
>Solution :
Try renaming the function as React sees no change in the object and likewise when you are using an array or object in a state. Try to copy them out by storing them in a new variable.
setRecords(
const newRecords = records.map((record) => {
if (record.id === id) {
return { id: id, correct: true };
} else {
return record;
}
})
//seting this now triggers an update
setRecords(newRecords);
);
Then as per react documentation it’s better to listen to changes with lifecycle methods and not setting state immediately after they are changed because useState is asynchronous.
so use useEffect to listen to the changes to set is Complete
useEffect(() => {
isComplete(records)
}, [records])
I hope this helps you?