使用 Axios 的简单 React API 请求

Simple React API requests with Axios

我正在尝试为 API 调用创建一个包装器,但我认为我遗漏了一些东西。承诺将帖子存储在 this.post 中,但我无法找到 return 数据的正确方法。

到目前为止我试过这个:

import axios from 'axios';

const CallumAPI = {
  posts: [

  ],
  all: function() {
    axios.get('http://callum.dev/api/posts')
      .then(res => {
        this.posts = res.data.posts;
      })
    return this.posts;
  }
}

export default CallumAPI

在我的包装器中,我试图 return 帖子,以便在我的组件中我可以将它们全部列出。这是组件代码:

<div>
  <ul>
    {
      CallumAPI.all().map(p => (
        <li key={p.id}>
          <Link to={'/post/${p.slug}'}>{p.name}</Link>
        </li>
      ))
    }
  </ul>
</div>

您无法直接从 axios 访问数据,因为它总是 return promise,因此您需要 callback function 或需要访问一旦数据可用,它就会通过 then

您可以执行以下操作:

像这样更改 CallumAPI :

const CallumAPI = {
  posts: [

  ],
  all: function() {
    return axios.get('https://jsonplaceholder.typicode.com/users') // change your api url
      .then(res => {
        this.posts = res.data;
        return this.posts; // return data so we can use
      })
  }
}

像这样的组件:

componentWillMount() {
    CallumAPI.all().then(posts => {
        console.log(posts);
        this.setState({posts}); // set state on data fetch so UI will render 
    });
}

render() {
    const { posts } = this.state;
    return (
        <ul>
        { posts.map(p => (
            <li key={p.id}>
                { p.name }
            </li>
            )) }
        </ul>
    );
}

这里是WORKING DEMO

axios 请求是一个异步调用,您甚至在承诺得到解决之前就返回了数组。此外,您的渲染函数中不应该有异步请求。您宁愿希望它调用一次并存储结果。在 componentDidMount 函数中提出您的 async 请求。

您可以更改 all 函数以接收 callback 函数并将响应传递给它。

const CallumAPI = {
  posts: [

  ],
  all: function(cb) {
    axios.get('http://callum.dev/api/posts')
      .then(res => {
        cb(res.data.posts);
      })
  }
}


componentDidMount() {
    CallumAPI.all(this.updateResult);
}

updateResult = (res) => {
    this.setState({res})
}

render() {
<div>
  <ul>
    {
      this.state.res.map(p => (
        <li key={p.id}>
          <Link to={`/post/${p.slug}`}>{p.name}</Link>
        </li>
      ))
    }
  </ul>
</div>
}