I'm working on a trivia app using ReactjS and every time I try to update my state named "game", I get the following error message:
Uncaught TypeError: game is undefined.
My webapp is structured as follows: App -> Question -> Answers.
in App:
const [game, setGame] = React.useState([]);
function holdAnswer(qKey) {
console.log(qKey);
setGame((oldGame) => {
oldGame.map((element) => {
return qKey === element.key ? {} : element;
});
});
console.log(qKey);
}
React.useEffect(function () {
console.log("Effect ran");
fetch("https://opentdb.com/api.php?amount=5")
.then((res) => res.json())
.then((data) =>
setGame(
data.results.map(function (element) {
return {
...element,
key: uniqid(),
answers: arrayShuffle([
...element.incorrect_answers.map(
(x) => new AnswerObj(x, false, uniqid())
),
new AnswerObj(element.correct_answer, false, uniqid()),
]),
};
})
)
);
console.log(game);
}, []);
var wholeQ = game.map((element) => {
return (
<Question wQ={element} holdAnswer={() => holdAnswer(element.key)} />
);
});
in Question Component:
export default function Question(props) {
const answers = arrayShuffle(props.wQ.answers).map((element) => {
return <Answers wholeAnswer={element} holdAnswer={props.holdAnswer} />;
});
return (
<div className="question">
<p>{decode(props.wQ.question)}</p>
<div className="answer-buttons-wrapper">{answers}</div>
</div>
);
}
in Answers Component:
export default function Answers(props) {
return (
<button className="answer-button" onClick={props.holdAnswer}>
{decode(props.wholeAnswer.answer)}
</button>
);
}
CodePudding user response:
I believe the problem lies in the following block:
function holdAnswer(qKey) {
console.log(qKey);
setGame((oldGame) => {
oldGame.map((element) => {
return qKey === element.key ? {} : element;
});
});
console.log(qKey);
}
As setGame
ends up not returning anything and therefor sets the state with an undefined
value.
To address this we can remove the curly-braces in setGame
in-order to make it an "implicit return".
Alternatively, we can add a return statement before the mapping function.
// Either this ->
setGame((oldGame) =>
oldGame.map((element) => {
return qKey === element.key ? {} : element;
});
);
// Or this ->
setGame((oldGame) => {
return oldGame.map((element) => {
return qKey === element.key ? {} : element;
});
});