【问题标题】:Fetch is still pending in react api callReact api 调用中的 Fetch 仍在等待中
【发布时间】:2020-11-15 05:11:14
【问题描述】:

我有一个反应组件。如果我用户单击父组件上的链接到,他们就可以降落在这个子组件上。但是,如果他们刷新页面,或者直接转到链接,他们就没有数据,所以我需要自己再次调用 api 来获取那个唯一的 id。

当我进行 api 调用时(当问题未定义时),它可以工作,但我得到了一个已经履行的承诺,没有数据。如何获取对象?

class Issue extends React.Component {
       

            getIssue = async (id) => {
                try {
                    const endpoint = `https://api.github.com/repos/facebook/create-react-app/issues/${id}`;
                    const response = await fetch(endpoint);
                    const data = await response.json();
                    return data;
                } catch (error) {
                    console.log(error);
                }
            }
        
    
        // }
        render(){
            
            let { issue } = this.props.location;
            console.log(issue);
    
            if(issue === undefined){
                console.log('No Data');
                issue = this.getIssue(this.props.match.params.id);
                console.log(issue);
            } else {
                console.log('Data');
            }
    
            return (
            <h1>ff</h1>
                
            )
        }
    }

【问题讨论】:

  • 如果问题未定义,则渲染加载组件。并在 componentDidMount() 中调用你的 api
  • 我该怎么做?
  • 如果在 getIssue 方法中 console.log(id)try 之前看到有效 id 吗?

标签: javascript reactjs


【解决方案1】:

原因是你的getIssue()async 函数,它会返回一个你必须稍后处理的promise。在您的 render() 方法中,您没有这样做,您必须使用 getIssue()then() 链接,您可以从 Promise 获取数据:

render() {
  let { issue } = this.props.location;
  console.log(issue);

  if(issue === undefined) {
    console.log('No Data');
    this.getIssue(this.props.match.params.id)
      .then(response => {
        console.log(response);
      });
  } else {
    console.log('Data');
  }
  
  return (
    <h1>ff</h1>
  )
}

【讨论】:

  • OP 说“我得到了一个已经履行的承诺,没有数据”,所以他们似乎知道 getIssue 正在返回一个承诺,只是它没有解决有任何数据......(虽然我可能误解了这个问题)
  • 是的,我现在对误解的想法完全一样 :) 已经有很多答案了,我希望一个是正确的......
【解决方案2】:

render() 期间不能调用异步函数 您应该对 useEffect 钩子(如果使用钩子)或 componentDidMount 或 React 类的生命周期之一进行异步调用。

一个例子:

class Issue extends React.Component {
  constructor() {
    this.state = {
      issue: null
    }
       
  componentDidMount() {
    const { issue } = this.props.location;
    if (!issue) {
      getIssue(this.props.match.params.id).then(data => {
        this.setState({ issue: data });
       }
    }
            
     getIssue = async (id) => {
                try {
                    const endpoint = `https://api.github.com/repos/facebook/create-react-app/issues/${id}`;
                    const response = await fetch(endpoint);
                    const data = await response.json();
                    return data;
                } catch (error) {
                    console.log(error);
                }
            }
        
    
        // }
        render(){
            
            let { issue } = this.state;
            console.log(issue);
    
            return (
            <h1>ff</h1>
                
            )
        }
    }

【讨论】:

    【解决方案3】:

    两个问题:

    1. 获取用法 - 只使用直接结果而不是数据,如下所示:

    const url = 'https://api.github.com/repos/facebook/create-react-app/issues/20'
    
    const getData = async () => {
      const data = await fetch(url);
      console.log(data)
    }
    
    getData();
    1. useEffectcomponentDidMount 中使用异步 - 要在useEffect 中使用,您可以参考:How to call an async function inside a UseEffect() in React?

    【讨论】:

      【解决方案4】:

      重写您的组件以使用状态,重写getIssue 以使用Promise(更适合这里)并将其移至componentDidMount 方法。

      class Issue extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            data: null
          };
        }
      
        componentDidMount() {
          const id = this.props.match.params.id;
          const endpoint = `https://api.github.com/repos/facebook/create-react-app/issues/${id}`;
      
          fetch(endpoint)
            .then(response => response.json())
            .then(data => this.setState({ data }))
            .catch(err => console.log(err));
        }
      
        render() {
          return <h1>{this.state.data ? this.state.data.title : "Loading..."}</h1>;
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-05
        • 2020-07-31
        • 1970-01-01
        • 2021-05-05
        • 2022-12-02
        • 1970-01-01
        • 2021-08-09
        相关资源
        最近更新 更多