如何在React with Asynchronous中使用API​​?

时间:2017-07-26 14:12:30

标签: javascript api reactjs

所以我试图用React弄脏手。我非常决定使用ReactJS编写 wikipedia viewer 项目。然而,在使用React组件从维基百科的API获取数据后,我昨天碰到了一堵砖墙。我认为它与异步调用有关。

我定义了一个接受查询并将其注入API网址的常量: javascript const apiUrl = query => `https://crossorigin.me/https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=${query}` 然后我定义了一个在ComponentDidMount状态中异步获取API的类:

class Wiki extends React.Component {
constructor(props){
    super(props);
  console.log('Inside Constructor')
}
componentWillMount(){
  this.setState = {
    wikiData: undefined
  }
  console.log('Before fetch')
    fetch(apiUrl(this.props.query))
    .then(console.log('fetch successful'))
    .then(response => {
        if(!response.ok){
            throw Error("Response not ok")
        }
        return response
    })
    .then(data => data.json())
    .then(data => {
        this.setState ={
            wikiData: data
        }
      console.log(data)
    })

}
render(){
    if(!this.state.wikiData == null) return <p>No answer</p>
    else{
    return (
        <div>
            <h1>Something happened</h1>
        <h2>{this.state.wikiData[0]}</h2>
        </div>
    )
    }
}

}

当我在app组件中调用它时,我得到一个TypeError sying&#34;无法读取属性&#39; wikiData&#39; of null&#34;之后数据从调用返回并且不再为null,但这会导致渲染中断。 Console messaqges 我确实尝试使用componentDidMount,但这也不起作用。 我不知道该怎么做,我想了解这个过程。 这是我的代码: https://codepen.io/Banhawy/pen/eEmQBW?editors=1010

我想知道只有在调用API返回数据后才能呈现组件,这样我才能在呈现之前访问和处理它。

4 个答案:

答案 0 :(得分:1)

在说服务响应任何响应之前调用render方法时,你是对的。

因此,您必须通过显示例如加载微调器来调整渲染,而未定义wikiData字段,并且当服务返回数据时,您将渲染wikiData。

答案 1 :(得分:1)

我已经对您的代码进行了一些修改,并发表了一些意见,希望可以帮助您。

class Wiki extends React.Component {

  constructor(props) {
    super(props);

    // this.state, not this.setState.
    // Also, it helps if you set your initial value to the value
    // to what you expect from your fetch (ie an array, albeit empty)
    this.state = { wikiData: [] }
  }

  // componentDidMount rather than componentWillMount
  // https://daveceddia.com/where-fetch-data-componentwillmount-vs-componentdidmount/
  componentDidMount() {
    fetch(apiUrl(this.props.query))
      .then(response => {
      .then(data => data.json())
      .then(data => this.setState = { wikiData: data }
      });
  }

  render() {

    // Check to see if your initial state is empty or not
    if (!this.state.wikiData.length) return <p>No answer</p>

    // No need for your else here. If your state is not empty, the first
    // return doesn't run, but this one does as a default.
    return (
      <div>
        <h1>Something happened </h1>
        <h2>{this.state.wikiData[0]}</h2>
      </div>
    )
  }

}

答案 2 :(得分:0)

您在componentWillMount中输了一个拼写错误,您写了this.setState而不是this.state。我还建议你将这个声明移到构造函数中:

class Wiki extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      wikiData: undefined
    }
  }
  ...
}

答案 3 :(得分:0)

您的代码中存在一些错误,请允许我扩展。

首先,您应该在类构造函数上拥有组件默认状态,因此请在方法componentWillMount上移动前三行。

其次,您的默认状态是错误的:

this.setState = {
    wikiData: undefined
}

this.setState是一个函数,用于设置应使用this.state的默认状态。