在组件上获取数据确实通过异步等待安装了

时间:2019-09-07 11:49:37

标签: reactjs asynchronous

我试图在componentDidMount上获取一些数据以将状态设置为react。

我在componentdidMount上使用asyn等待,获取一些数据,等待它完成,然后将我的状态设置为该数据。

我遵循本文的完全相同的模式:https://medium.com/front-end-weekly/async-await-with-react-lifecycle-methods-802e7760d802

这是我的componentDidMount方法:

  const url = "http://localhost:3001";
  const opts = {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ query })
  };
  await fetch(url, opts)
    .then(res => res.json())
    .then(data => this.setState({
      photographers: data
    }))
    .catch(console.error);
}

然后在我的渲染方法中,我尝试使用状态值。但是它的状态未定义:

render() {

console.log('here:', this.state)

return (
  <React.Fragment>
    <div className="red ba">Hella!</div>
    <List photographers={this.state.photographers}/>
  </React.Fragment>
  )
}

我曾经多次使用过asunc,我知道它是如何工作的,但是为什么这不起作用?谢谢!

3 个答案:

答案 0 :(得分:1)

您应该删除.then().catch()方法,它们正在返回promise,相反,您应该使 componentDidMount异步获取等待状态

constructor(props) {
    super(props)
    this.state = {
      photographers: []
    }
  }

async componentDidMount() {
  const url = "http://localhost:3001";
  const opts = {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ query })
  };
  try {
    const response = await fetch(url, opts)
    if (!response.ok) {
      throw Error(response.statusText);
    }
    const json = await response.json();
    console.log(json)
    this.setState({ photographers: json });
  } catch(error) {
    console.log(error)
  }
}

此外,您还可以将try和catch包含在fetch中,这样您就可以处理catch块中的错误,或者如果response.ok不是true

答案 1 :(得分:1)

这是异步javascript的工作方式,代码将运行完成,这意味着,当您运行网络请求并在componentDidMount中写入await时,下一个代码中的任何内容都不会停止并等待,一切将照常进行(并且当网络请求完成时,将执行then代码中的代码),请注意,等待是写然后阻塞的一种更简便的方法(实际上没有等待)

因为您不能在等待时停止渲染,所以应该在数据不存在时进行处理,通常会显示一个加载屏幕,您可以执行以下操作:

// You should initialise the photographers in the state to be null
render() {

console.log('here:', this.state)

return this.state.photographers !== null ? (
  <React.Fragment>
    <div className="red ba">Hella!</div>
    <List photographers={this.state.photographers}/>
  </React.Fragment>
  ) : (<div>Loading...</div>)
}

答案 2 :(得分:0)

您正在尝试将异步调用的两种语法结合在一起-async / await和.then()。catch() 坚持下去。

我个人更喜欢将异步代码放在其他函数中,并在componentDidMount()中使用

const fetchPhotographers = () => {  
  const url = "http://localhost:3001";
  const opts = {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ query })
  };
  fetch(url, opts)
    .then(res => res.json())
    .then(data => this.setState({
      photographers: data
    }))
    .catch(console.error);
}

componentDidMount() {
 fetchPhotographers()
}