在 React.js 中使用 Async/Await 和 Axios

Use Async/Await with Axios in React.js

正在关注

How to use async/await with axios in react

我正在尝试在 React.js 应用程序中使用 Async/Await 向我的服务器发出简单的获取请求。 服务器在 /data 处加载一个简单的 JSON,看起来像这样

JSON

{
   id: 1,
   name: "Aditya"
}

我可以使用简单的 jquery ajax get 方法将数据获取到我的 React 应用程序。 但是,我想利用 axios 库和 Async/Await 来遵循 ES7 标准。 我当前的代码如下所示:

class App extends React.Component{
 async getData(){
     const res = await axios('/data');
     console.log(res.json());
 }
 render(){
     return(
         <div>
             {this.getData()}
         </div>
     );
 }
}

使用这种方法我得到以下错误:

Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

我没有正确执行它吗?

跳出两个问题:

  1. 你的 getData 从来没有 return 任何东西,所以它的承诺(async 总是 return 一个承诺)将通过 undefined 如果不拒绝

  2. 错误消息清楚地表明您正在尝试直接呈现 promise getData returns,而不是等待它解决然后呈现 fulfillment 值

寻址 #1:getData 应该 return 调用 json:

的结果
async getData(){
   const res = await axios('/data');
   return await res.json();
}

Addressig #2:我们必须查看更多您的代码,但从根本上说,您做不到

<SomeElement>{getData()}</SomeElement>

...因为那不会等待决议。您需要改为使用 getData 来设置状态:

this.getData().then(data => this.setState({data}))
              .catch(err => { /*...handle the error...*/});

...并在渲染时使用该状态:

<SomeElement>{this.state.data}</SomeElement>

更新:既然您已经向我们展示了您的代码,您需要做类似的事情:

class App extends React.Component{
    async getData() {
        const res = await axios('/data');
        return await res.json(); // (Or whatever)
    }
    constructor(...args) {
        super(...args);
        this.state = {data: null};
    }
    componentDidMount() {
        if (!this.state.data) {
            this.getData().then(data => this.setState({data}))
                          .catch(err => { /*...handle the error...*/});
        }
    }
    render() {
        return (
            <div>
                {this.state.data ? <em>Loading...</em> : this.state.data}
            </div>
        );
    }
}

进一步更新:您已表示偏好在 componentDidMount 中使用 await 而不是 thencatch .为此,您可以在其中嵌套一个 async IIFE 函数并确保该函数不会抛出异常。 (componentDidMount 本身不能是 async,没有任何东西会消耗那个承诺。)例如:

class App extends React.Component{
    async getData() {
        const res = await axios('/data');
        return await res.json(); // (Or whatever)
    }
    constructor(...args) {
        super(...args);
        this.state = {data: null};
    }
    componentDidMount() {
        if (!this.state.data) {
            (async () => {
                try {
                    this.setState({data: await this.getData()});
                } catch (e) {
                    //...handle the error...
                }
            })();
        }
    }
    render() {
        return (
            <div>
                {this.state.data ? <em>Loading...</em> : this.state.data}
            </div>
        );
    }
}

根据过去几个月的经验,我意识到实现这一目标的最佳方法是:

class App extends React.Component{
  constructor(){
   super();
   this.state = {
    serverResponse: ''
   }
  }
  componentDidMount(){
     this.getData();
  }
  async getData(){
   const res = await axios.get('url-to-get-the-data');
   const { data } = await res;
   this.setState({serverResponse: data})
 }
 render(){
  return(
     <div>
       {this.state.serverResponse}
     </div>
  );
 }
}

如果您尝试对点击等事件发出 post 请求,则对事件调用 getData() 函数并像这样替换它的内容:

async getData(username, password){
 const res = await axios.post('url-to-post-the-data', {
   username,
   password
 });
 ...
}

此外,如果您在组件即将加载时发出任何请求,则只需将 async getData() 替换为 async componentDidMount() 并像这样更改渲染函数:

render(){
 return (
  <div>{this.state.serverResponse}</div>
 )
}
  useEffect(() => {     
    const getData = async () => {  
      await axios.get('your_url')  
      .then(res => {  
        console.log(res)  
      })  
      .catch(err => {  
        console.log(err)  
      });  
    }  
    getData()  
  }, [])
const axios = require('axios').default;

const sendGetRequest = async () => {
    try {
        const resp = await axios.get('https://jsonplaceholder.typicode.com/posts', {
            headers: {
                'authorization': 'Bearer YOUR_JWT_TOKEN_HERE'
            }
        });

        console.log(resp.data);
    } catch (err) {
        // Handle Error Here
        console.error(err);
    }
};

sendGetRequest();