如何使用 API 并在列表中显示结果
Posted
技术标签:
【中文标题】如何使用 API 并在列表中显示结果【英文标题】:How to Consume an API & Display Results in a List 【发布时间】:2019-11-29 22:59:21 【问题描述】:我正在使用 ReactJS 和以下 API 端点创建一个琐事游戏:https://opentdb.com/api.php?amount=5&difficulty=medium&type=boolean
据我了解,我想在 ComponentDidMount()
生命周期方法中使用 API。从那里我尝试map()
覆盖此响应中的每个项目(总共应该有 5 个问题),并将它们保存到一个空的问题数组(这是我的组件状态的一部分)。最后,我想将这些问题显示在一个列表中。
我尝试了各种角度,包括async await
、fetch()
& .then()
、using axios.get
等。这是我最近尝试的一个示例。我只是不确定如何使用 API,将这些问题保存到空问题数组中以进行状态,然后迭代,并在 DOM 中呈现问题。
请注意:我尝试过console.log(this.state.questions)
,它将响应显示为代码 200,以及我的原始 API 端点 URL,但没有问题数据。我现在不明白问题在哪里!请帮忙!
class App extends React.Component
constructor(props)
super(props)
this.state =
questions: [],
score: 0,
current: 0,
loading: false
async componentDidMount()
try
this.setState( loading: true )
this.setState( questions: await fetch('https://opentdb.com/api.php?amount=5&difficulty=medium&type=boolean'), loading: false )
console.log("state", this.state.questions);
console.log("props", this.props.questions);
catch (err)
console.log(err)
componentDidUpdate()
console.log("component just updated!");
// another ComponentDidMount Attempt
// async componentDidMount()
// try
// this.setState(loading:true)
// this.setState(questions: await fetch('https://opentdb.com/api.php?amount=5&difficulty=medium&type=boolean'), loading: false)
// .then(questions => questions.json())
// .then(questions => this.setState(questions, loading:false))
// console.log("state", this.state.questions);
// console.log("props", this.props.questions);
// catch(err)
// console.log(err)
//
//
//
// attempt with axios ()
// componentDidMount()
// axios
// .get("https://opentdb.com/api.php?amount=5&difficulty=medium&type=boolean")
// .then(response =>
// this.setState( question: response.data.question );
// this.setState( category: response.data.category );
// // this.setState( type: response.data.type );
// // this.setState( url: response.data.url );
// // this.setState( score: response.data.score );
// console.log("axios GET worked");
// )
// .catch(err =>
// console.log(
// "Oops, something broke with GET in componentDidMount() - we've got a: ",
// err.message
// );
// );
//
// below is having an issue with .map() - maybe bc questions
// is object containing arrays(?)
//
// render()
// return (
// <div>
// this.state.loading
// ? "loading..."
// : <div>
//
// this.state.questions.map(question =>
// return(
// <div>
// <h3>Category: question.category</h3>
// <h4>Question: question.question</h4>
// </div>
// )
// )
//
// </div>
//
//
// <HomeCard />
// <QuizCard />
// <ResCard />
// </div>
// );
//
export default App;
【问题讨论】:
【参考方案1】:试试
async componentDidMount()
this.setState(
loading: true
);
try
const response = await fetch('https://opentdb.com/api.php?amount=5&difficulty=medium&type=boolean');
const data = await response.json();
this.setState(
questions: data.results,
loading: false
);
catch (err)
console.log(err)
https://codesandbox.io/s/sad-bogdan-g5mub 上的演示
【讨论】:
【参考方案2】:您的代码不起作用,因为对 setState 的调用也是异步的,因此您的 console.log(this.state.question);
是在状态更新之前执行的。为了解决这个问题,您可以将回调作为第二个参数传递给 setState,此回调将在状态更新后执行。
应该是这样的:
this.setState(
questions: await fetch('https://opentdb.com/api.php amount=5&difficulty=medium&type=boolean'),
loading: false
,
() =>
console.log("questions", this.state.questions);
console.log("loading", this.state.loading);
)
您可以在此处找到更多信息:https://reactjs.org/docs/faq-state.html#why-is-setstate-giving-me-the-wrong-value。
希望对你有所帮助。
【讨论】:
你的解释帮助我理解了我的代码中的错误,在状态和异步的上下文中!!谢谢多纳托!以上是关于如何使用 API 并在列表中显示结果的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中使用 .fileimporter 保存音频文件并检索文件并在 SwiftUI 列表中显示它们的文件名?
如何在 Android for Android api 11+ 的列表视图中显示联系人