由于某种原因,我无法访问结果数组中的“问题”键。有人可以帮忙吗?这只是我已经开始的一个辅助项目,并且已经花了好几个小时试图将这第一部分基本内容付诸实践。我至今仅使用React和API已有大约一周的时间,而且我经验不足,所以可以提供任何帮助。
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
constructor() {
super()
this.state = {
questionList: []
}
}
componentDidMount() {
fetch('https://opentdb.com/api.php?amount=10')
.then(resp => resp.json())
.then(resp => this.setState({ questionList: resp }))
}
render() {
return (
<div>{this.state.questionList.results[0].question}</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
这是API数据-
{
"response_code": 0,
"results": [
{
"category": "Entertainment: Film",
"type": "multiple",
"difficulty": "medium",
"question": "Which of the following James Bond villains is not affiliated with the SPECTRE organization?",
"correct_answer": "Auric Goldfinger",
"incorrect_answers": [
"Dr. Julius No",
"Rosa Klebb",
"Emilio Largo"
]
},
{
"category": "Geography",
"type": "multiple",
"difficulty": "hard",
"question": "The mountainous Khyber Pass connects which of the two following countries?",
"correct_answer": "Afghanistan and Pakistan",
"incorrect_answers": [
"India and Nepal",
"Pakistan and India",
"Tajikistan and Kyrgyzstan"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "In Team Fortress 2, which class wields a shotgun?",
"correct_answer": "Everyone Listed",
"incorrect_answers": [
"Heavy",
"Soldier",
"Engineer"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "easy",
"question": "Who is the leader of Team Mystic in Pokémon Go?",
"correct_answer": "Blanche",
"incorrect_answers": [
"Candela",
"Spark",
"Willow"
]
},
{
"category": "Science & Nature",
"type": "multiple",
"difficulty": "easy",
"question": "The medical term for the belly button is which of the following?",
"correct_answer": "Umbilicus",
"incorrect_answers": [
"Nevus",
"Nares",
"Paxillus"
]
},
{
"category": "Entertainment: Cartoon & Animations",
"type": "multiple",
"difficulty": "easy",
"question": "What is lost in Hawaiian and is also the name of a little girl in a 2002 film which features a alien named "Stitch"?",
"correct_answer": "Lilo",
"incorrect_answers": [
"Lolo",
"Lucy",
"Lulu"
]
},
{
"category": "Entertainment: Cartoon & Animations",
"type": "multiple",
"difficulty": "hard",
"question": "In "Gravity Falls", what does Quentin Trembley do when he is driven out from the White House?",
"correct_answer": "Eat a salamander and jump out the window.",
"incorrect_answers": [
"Leave in peace.",
"Jump out the window.",
"Release 1,000 captive salamanders into the white house."
]
},
{
"category": "Entertainment: Television",
"type": "multiple",
"difficulty": "hard",
"question": "Who was the winner of "Big Brother" Season 10?",
"correct_answer": "Dan Gheesling",
"incorrect_answers": [
"Bryce Kranyik",
"Ryan Sutfin",
"Chris Mundorf"
]
},
{
"category": "General Knowledge",
"type": "multiple",
"difficulty": "easy",
"question": "Terry Gilliam was an animator that worked with which British comedy group?",
"correct_answer": "Monty Python",
"incorrect_answers": [
"The Goodies‎",
"The League of Gentlemen‎",
"The Penny Dreadfuls"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "easy",
"question": "In Counter-Strike: Global Offensive, what's the rarity of discontinued skins called?",
"correct_answer": "Contraband",
"incorrect_answers": [
"Discontinued",
"Diminshed",
"Limited"
]
}
]
}
谢谢!
答案 0 :(得分:1)
这肯定会失败,因为您正在调用异步操作,但是您的渲染显式依赖于此:
{this.state.questionList.results[0].question}
您可能会收到
Cannot read property 'question' of undefined
或
无法读取
property '0' of undefined
最基本的解决方案是检查questionList
内是否确实有一些数据。
注意:数组中的questionList
,而不是对象。
render() {
if (this.state.questionList.length === 0) {
return null;
}
return (
<div>{this.state.questionList[0].results[0].question}</div>
);
}
尽管最好,但最长的解决方案是逐步检查questionList
具有正确的结构:
{this.state.questionList[0]
&& this.state.questionList.results
&& this.state.questionList.results[0]
&& this.state.questionList.results[0].question}
答案 1 :(得分:1)
正如其他人所指出的,您的API调用将花费一段时间,并且App
将在完成之前呈现,因此在呈现时您的数据还不存在。您基本上是在尝试获取尚不存在的数据。
我喜欢在状态上显示一个loading
标志来显示正在加载的东西,以及一个error
标志来标识任何传入的错误。
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
constructor() {
super()
this.state = {
questionList: {
isLoading: true,
error: null,
data: null,
}
}
}
componentDidMount() {
fetch('https://opentdb.com/api.php?amount=10')
.then(resp => resp.json())
.then(resp => this.setState(
{questionList:
{data: resp, isLoading: false, error: null}
}))
.catch(e => this.setState({questionList: {data: null, error: e, data: null}}))
}
render() {
if (this.state.questionList.isLoading)
return <Loading />
if (this.state.questionList.error)
return <Error error={this.state.questionList.error} />
return (
<div>{this.state.questionList.data.results[0].question}</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
您可以而且应该在检查,数据修复等方面更加聪明……但这就是我如何处理它的要旨。
我还建议将您的API调用包装在模块中。因此,您可以说api.questions.getList().then(...)
而不是在组件中进行提取,而是可以将任何数据转换或其他难看的东西放入这些模块中。它与您的问题并没有真正的联系(反正这可能会过大了),但是由于您似乎是新手,所以我会为您解决。
答案 2 :(得分:0)
使用 console.log in render()
,您将看到状态为空,因为您调用了异步函数。
有:
您可以添加一些代码,例如:
render() {
if (this.state.questionList.length === 0) {
return '<div>Loading...</div>';
}
return (
<div>{this.state.questionList.results[0].question}</div>
)
}
答案 3 :(得分:-2)
我不确定您的结果在呈现时是否会返回到该组件。我认为您需要运行检查以查看结果是否在那里。你可以尝试这样的事情,我们可以从这里去吗?
{this.state.questionList.results.length > 1 && this.state.questionList.results[0].question}