如何使用 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 awaitfetch() & .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 列表中显示它们的文件名?

Django:如何使用查询集并在模板中显示结果?

如何在 Android for Android api 11+ 的列表视图中显示联系人

如何使用 API 中的 HTML 标签并在页面上显示?

如何在 ios 中使用 json 解析获取数据并在另一个页面中显示结果?

如何使用数组并在 MsgBox VBA 中显示它们