繁体   English   中英

链接提取调用React.js

[英]Chaining Fetch Calls React.js

我正在制作一个必须从Github API获取某些数据的应用程序。 我需要获取名称,URL,语言和最新标签。 由于最新标记位于单独的url中,因此我需要在此处进行另一个访存调用以获取该数据。

我遇到了一定数量的错误。

第一个是typeError cannot read property 'name' of undefined 我确定这是从fetch调用到没有任何数据的标记URL。 我不太确定如何检查它是否未定义。 我尝试调用检查以查看typeof数据是否未定义等等,但仍然会收到错误。

第二个问题是我的标签网址数据未与其他数据一起显示。 我确定链接数据错误,因为当我单击添加按钮时,它会显示出来。

这是我的代码:

import React, { Component } from 'react'
import './App.css'

class App extends Component {
  state = {
    searchTerm: '',
    repos: [],
    favourites: []
  }

  handleChange = e => {
    const { searchTerm } = this.state

    this.setState({ searchTerm: e.target.value })

    if (searchTerm.split('').length - 1 === 0) {
      this.setState({ repos: [] })
    }
  }

  findRepos = () => {
    const { searchTerm } = this.state

    // First api call here
    fetch(`https://api.github.com/search/repositories?q=${searchTerm}&per_page=10&access_token=${process.env.REACT_APP_TOKEN}
`)
      .then(res => res.json())
      .then(data => {
        const repos = data.items.map(item => {
          const { id, full_name, html_url, language } = item
          const obj = {
            id,
            full_name,
            html_url, 
            language,
            isFavourite: false
          }

          // Second api call here. I need the data from map to get the tags for the correct repo
          fetch(`https://api.github.com/repos/${full_name}/tags`)
            .then(res => res.json())
            .then(data => {
              obj.latest_tag = data[0].name
            })
            .catch(err => console.log(err))

          return obj
        })

        this.setState({ repos })
      })
      .catch(err => console.log(err))
  }

render() {
  const { searchTerm, repos, favourites } = this.state

  return (
    <div className="App">
      <h1>My Github Favorites</h1>
      <input 
        type="text"
        placeholder="search for a repo..."
        value={searchTerm}
        onChange={e => this.handleChange(e)}
        onKeyPress={e => e.key === 'Enter' && this.findRepos()}
      />
      <button 
        type="submit" 
        onClick={this.findRepos}>
        Search
      </button>

     <div className="category-container">
      <div className="labels">
        <h5>Name</h5>
        <h5>Language</h5>
        <h5>Latest Tag</h5>          
      </div>

      // Here I list the data
      {repos.map(repo => (
        <div key={repo.id}>
          <a href={repo.html_url}>{repo.full_name}</a>
          <p>{repo.language}</p>
          {repo.latest_tag ? <p>{repo.latest_tag}</p> : <p>-</p>}
          <button onClick={() => this.addToFavs(repo)}>Add</button>
        </div>
      ))}   

      <h1>Favourites</h1>
      {favourites.map(repo => (
        <div key={repo.id}>
          <a href={repo.html_url}>{repo.full_name}</a>
          <p>{repo.language}</p>
          <p>{repo.latest_tag}</p>
          <button>Remove</button>
        </div>
      ))}   
    </div>
  </div>
  )
}
}

export default App

如果使用Promise.all(),则可以像下面这样重写代码。

findRepos = () => {
const { searchTerm } = this.state;

// First api call here
const first = fetch(
  `https://api.github.com/search/repositories?q=${searchTerm}&per_page=10&access_token=${
    process.env.REACT_APP_TOKEN
  }`
);
// Second api call here. I need the data from map to get the tags for the correct repo
const second = fetch(`https://api.github.com/repos/${full_name}/tags`);
Promise.all([first, second])
  .then((res) => Promise.all(res.map(r => r.json())))
  .then([data1, data2] => {
    data1.then((firstData) => {
      /*Do something you want for first.*/
    });
    data2.then((secondData) => {
      /*Do something you want for second.*/
    });
  })
  .catch((err) => console.log(err));
};

希望这对您有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM