在 React.js 中将 Async/Await 与 Axios 结合使用 [英] Use Async/Await with Axios in React.js

查看:30
本文介绍了在 React.js 中将 Async/Await 与 Axios 结合使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关注

如何在反应中使用 async/await 和 axios

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

JSON

<代码>{编号:1,名称:《阿迪亚》}

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

class App 扩展 React.Component{异步获取数据(){const res = await axios('/data');控制台日志(res.json());}使成为(){返回(<div>{this.getData()}

);}}

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

<块引用>

对象作为 React 子对象无效(找到:[object Promise]).如果您打算渲染一组子项,请改用数组.

我是否没有正确实施它?

解决方案

跳出两个问题:

  1. 你的 getData 永远不会返回任何东西,所以它的承诺(async 函数总是返回一个承诺)将用 undefined 实现,如果它不拒绝

  2. 错误消息清楚地表明您正在尝试直接呈现 getData 返回的承诺,而不是等待它解决然后呈现履行值

解决 #1:getData 应该返回调用 json 的结果:

async getData(){const res = await axios('/data');返回等待 res.json();}

地址 #2:我们必须查看更多您的代码,但从根本上说,您不能这样做

{getData()}

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

this.getData().then(data => this.setState({data})).catch(err => {/*...处理错误...*/});

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

{this.state.data}


更新:既然您已经向我们展示了您的代码,您需要执行类似的操作:

class App 扩展 React.Component{异步获取数据(){const res = await axios('/data');返回等待 res.json();//(管他呢)}构造函数(...参数){超级(...参数);this.state = {数据:空};}componentDidMount() {如果(!this.state.data){this.getData().then(data => this.setState({data})).catch(err => {/*...处理错误...*/});}}使成为() {返回 (<div>{this.state.data ?<em>正在加载...</em>: this.state.data}

);}}

进一步更新:您已经表明在 componentDidMount 中使用 await 而不是 then 和 <代码>捕获.您可以通过在其中嵌套一个 async IIFE 函数并确保该函数不会抛出来做到这一点.(componentDidMount 本身不能是 async,没有任何东西会消耗那个承诺.)例如:

class App 扩展 React.Component{异步获取数据(){const res = await axios('/data');返回等待 res.json();//(管他呢)}构造函数(...参数){超级(...参数);this.state = {数据:空};}componentDidMount() {如果(!this.state.data){(异步() => {尝试 {this.setState({data: await this.getData()});}赶上(e){//...处理错误...}})();}}使成为() {返回 (<div>{this.state.data ?<em>正在加载...</em>: this.state.data}

);}}

Following

How to use async/await with axios in react

I am trying to make a simple get request to my server using Async/Await in a React.js App. The server loads a simple JSON at /data which looks like this

JSON

{
   id: 1,
   name: "Aditya"
}

I am able to get the data to my React App using simple jquery ajax get method. However, I want to make use of axios library and Async/Await to follow ES7 standards. My current code looks like this:

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

Using this approach I get the following error:

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

Am I not implementing it correctly?

解决方案

Two issues jump out:

  1. Your getData never returns anything, so its promise (async functions always return a promise) will be fulfilled with undefined if it doesn't reject

  2. The error message clearly shows you're trying to directly render the promise getData returns, rather than waiting for it to settle and then rendering the fulfillment value

Addressing #1: getData should return the result of calling json:

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

Addressig #2: We'd have to see more of your code, but fundamentally, you can't do

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

...because that doesn't wait for the resolution. You'd need instead to use getData to set state:

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

...and use that state when rendering:

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


Update: Now that you've shown us your code, you'd need to do something like this:

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>
        );
    }
}

Futher update: You've indicated a preference for using await in componentDidMount rather than then and catch. You'd do that by nesting an async IIFE function within it and ensuring that function can't throw. (componentDidMount itself can't be async, nothing will consume that promise.) E.g.:

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>
        );
    }
}

这篇关于在 React.js 中将 Async/Await 与 Axios 结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆