I'm trying to get into details with React and make a simple Quiz app. I get some locally saved data and render it on the page. However, when I try to change state with data from true to false (toggle function), I get an error. Once it's triggered I get the following error: Cannot read properties of undefined (reading 'map'). Could you please let me know where the bug is? Thanks in advance.
const questBlocks = data.map((elem, index) => {
const ansBlocks = elem.answers.map((ans) => (
<Answer
toggle={toggle}
isSelected={ans.selected}
ans={ans.text}
key={ans.id}
id={ans.id}
/>
));
return (
<div key={index}>
<Question question={elem.question} />
<div className="answerCont">{ansBlocks}</div>
</div>
);
});
function toggle(id) {
setData((prevData) => {
return prevData.map((question) => {
return question.answers.map((answer) => {
return answer.id === id
? { ...answer, selected: !answer.selected }
: answer;
});
});
});
}```
CodePudding user response:
A question
appears to have an answers
property, and probably has other properties too (such as the question text). When toggling an answer, you shouldn't change the question to be an array of answers, as your current code is doing - the question should remain an object with an answers
property.
This
setData((prevData) => {
return prevData.map((question) => {
return question.answers.map((answer) => {
return answer.id === id
? { ...answer, selected: !answer.selected }
: answer;
});
});
});
should be
setData((prevData) => (
data.map((question) => ({
...question,
answers: question.answers.map((answer) => (
answer.id === id
? { ...answer, selected: !answer.selected }
: answer
))
}))
));
The callback for the state setter very likely isn't needed here either.
Also, if the questions have unique IDs, you should use those for keys instead of using indices.
CodePudding user response:
The error is coming from the setData function. The data that you are trying to map over is undefined, so you cannot use the map method on it. You need to make sure that the data you are trying to map over is defined before using the map method on it.