[英]Type Error when i try to Render Objects out of an array
i get the following error when i try to load questions(Array) for a quiz from a db.json server.当我尝试从 db.json 服务器加载测验的问题(数组)时出现以下错误。
TypeError: this.state.questions[this.state.currentQuestion] is undefined类型错误:this.state.questions[this.state.currentQuestion] 未定义
here is a sandbox of my project (relevant classes are play_quiz.js and db.json https://codesandbox.io/s/kjllt?file=/quiz-project/server/db.json这是我项目的沙箱(相关类是 play_quiz.js 和 db.json https://codesandbox.io/s/kjllt?file=/quiz-project/server/db.json
the error occurs in line 79 of play_quiz.js错误发生在 play_quiz.js 的第 79 行
it worked just fine when i did it without the json server but not it seems to have some kind of problem recognising the content of the array.当我在没有 json 服务器的情况下执行它时它工作得很好但不是它似乎在识别数组内容时遇到某种问题。 I hope someone can help me
我希望有一个人可以帮助我
As discussed in the comments, the issue is that when the component renders for the first time, this.state.questions
is an empty array as set in the state's initial state.正如评论中所讨论的,问题是当组件第一次呈现时,
this.state.questions
是一个空数组,如状态初始 state 中所设置的那样。
Because of this, this.state.questions[0]
returns undefined, until the API response finishes (which is started by getRandomizedQuestions()
which is called by componentDidMount
after the component has been rendered and mounted).因此,
this.state.questions[0]
返回 undefined,直到 API 响应完成(由getRandomizedQuestions()
启动,在组件渲染和安装后由componentDidMount
调用)。
You need to handle this case.你需要处理这种情况。 The way to solve it depends on how you want to solve it and what you want to show to the user while it's loading.
解决它的方法取决于你想如何解决它以及你想在加载时向用户展示什么。 Here's a few solutions:
这里有几个解决方案:
render() {
if (this.state.questions.length < 1) {
return <div className="quiz-window">Loading...</div>;
}
return (
<div className="quiz-window">
// ...
</div>
);
}
render() {
return (
<div className="quiz-window">
{this.state.showScore ? (
<div className="score-section">
korrekt beantwortet: {this.state.score} von{" "}
{this.state.questions.length}
</div>
) : this.state.questions.length > 0 ? (
<>
<div className="question-section">
<div className="question-count">
<span>Frage {this.state.currentQuestion + 1}</span>/
{this.state.questions.length}
</div>
<div className="question-text">
{this.state.questions[this.state.currentQuestion].title}
</div>
</div>
<div className="answer-section">
{this.state.questions[this.state.currentQuestion].answers.map(
(answer) => (
<button
onClick={() => this.handleAnswerOptionClick(answer.isCorrect)}
>
{answer.title}
</button>
)
)}
</div>
</>
) : (
<p>Loading</p>
)}
</div>
);
}
Alternatively, if it's possible that the API returns an empty array and you want to handle that as a separate case:或者,如果 API 可能返回一个空数组并且您想将其作为单独的情况处理:
class Play_quiz extends React.Component {
state = {
currentQuestion: 0,
showScore: false,
score: 0,
questions: [],
isLoading: true,
};
// ...
getRandomizedQuestions = () => {
const apiUrl = "http://localhost:3001/questions";
fetch(apiUrl)
.then((response) => response.json())
.then(
(result) => {
console.log("From database:");
console.log(result);
let amountOfQuestions = result.length;
let randomizedResult = [];
for (let i = 0; i < amountOfQuestions; i++) {
let randomIndex = Math.floor(Math.random() * result.length);
randomizedResult.push(result[randomIndex]);
result.splice(randomIndex, 1);
}
this.setState({
questions: randomizedResult,
isLoading: false
});
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
},
(error) => {
console.log("An unexpected error occurred", error);
}
);
};
// ...
render() {
if (this.state.isLoading) {
return <div className="quiz-window">Loading...</div>;
}
return (
<div className="quiz-window">
// ...
</div>
);
}
}
See also: Why calling react setState method doesn't mutate the state immediately?另请参阅:为什么调用 react setState 方法不会立即改变 state?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.