在componentDidMount中从一个axios获取数据传递到另一个axios

3

在componentDidMount中,我试图从/api/topics/${params.TopicId}路由获取名为topic的数据,然后我只想将topic.user_id发送到另一个路由,并获得整个用户作为响应。但是这不起作用,因为它们同时发送请求,所以topic.user_id的状态为空。有没有办法可以取出响应的一部分并将其提供给另一个请求?我正在componentDidMount中进行此操作,因此它将在组件呈现之前完成。

componentDidMount() {
    const {
      match: { params }
    } = this.props;

    axios
      .get(`/api/topics/${params.TopicId}`)
      .then(response => {
        this.setState({ topic: response.data });
      })
      .catch(function(error) {
        console.log(error);
      });

    axios
      .get(`/api/users/${this.state.topic.user_id}`)
      .then(response => {
        this.setState({ user: response.data });
      })
      .catch(function(error) {
        console.log(error);
      });
  }
3个回答

5
componentDidMount() {
  const {
    match: { params }
  } = this.props;

  fetch(`/api/topics/${params.TopicId}`,(response)=>{
    this.setState({ topic: response.data } , 
      {
        fetch(`/api/users/${this.state.topic.user_id}` ,(response)=>{
          this.setState({ user: response.data });
        } )
      });

}

const fetch = (uri,callBack) =>{
  axios
  .get(uri)
  .then(response => {
    callBack(response)
  })
  .catch(function(error) {
    console.log(error);
  });
}

最好使用setState()的回调函数参数

setState(updater[, callback])

因为你需要在下一次获取之前更新状态。请参考:https://reactjs.org/docs/react-component.html#setstate

"user_id" 在上一个请求中返回,因此下一个请求可以立即开始,无需等待状态更新。 - Brian Adams
你如何确定哪一行会先执行?setState还是axios get?它们都是异步的。 - Naor Tedgi
从第一个 axios.get 调用的响应中提取 user_id,一旦第一个调用返回,就开始下一个调用,同时设置状态的 topic 部分。然后在第二个请求返回时设置状态的 user 部分。由于 usertopic 状态是独立的,它们可以以任何顺序设置,并且立即启动第二个请求将提高性能。 - Brian Adams

4
您可以像这样链接您的Promises
componentDidMount() {
  const {
    match: { params }
  } = this.props;

  axios
    .get(`/api/topics/${params.TopicId}`)
    .then(response => {
      this.setState({ topic: response.data });
      return axios.get(`/api/users/${response.data.user_id}`);
    })
    .then(response => {
      this.setState({ user: response.data });
    })
    .catch(function(error) {
      console.log(error);
    });
}

非常感谢,我不知道你可以这样做。非常简单易懂的解决方案 :D - db14

0
你可以使用回调函数。
const func = (id, cb) => axios
  .get(`/api/topics/${id}`)
  .then(response => {
    this.setState({ topic: response.data });
    cb(response.data.user_id);
  })
  .catch(function(error) {
    console.log(error);
  });

这样,您可以调用...

func(params.TopicId, user_id => axios
  .get(`/api/users/${user_id}`)
  .then(response => {
    this.setState({ user: response.data });
  })
  .catch(function(error) {
    console.log(error);
  })
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接