在 React.js 中将 Async/Await 与 Axios 结合使用 [英] Use Async/Await with Axios in React.js
问题描述
关注
我正在尝试使用 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]).如果您打算渲染一组子项,请改用数组.
我是否没有正确实施它?
跳出两个问题:
你的
getData
永远不会返回任何东西,所以它的承诺(async
函数总是返回一个承诺)将用undefined
实现,如果它不拒绝错误消息清楚地表明您正在尝试直接呈现
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:
Your
getData
never returns anything, so its promise (async
functions always return a promise) will be fulfilled withundefined
if it doesn't rejectThe 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屋!