Javascript 在 React.js 中将 Async/Await 与 Axios 结合使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46733354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use Async/Await with Axios in React.js
提问by Singh
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 /datawhich looks like this
我正在尝试使用 React.js 应用程序中的 Async/Await 向我的服务器发出一个简单的 get 请求。服务器加载一个简单的 JSON /data,看起来像这样
JSON
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:
我能够使用简单的 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>
);
}
}
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.
对象作为 React 子对象无效(找到:[object Promise])。如果您打算渲染一组子项,请改用数组。
Am I not implementing it correctly?
我没有正确实施它吗?
回答by T.J. Crowder
Two issues jump out:
两个问题跳出来:
Your
getDatanever returns anything, so its promise (asyncfunctions always return a promise) will resolve withundefinedwhen it resolvesThe error message clearly shows you're trying to directly render the promise
getDatareturns, rather than waiting for it to resolve and then rendering the resolution
你
getData从不返回任何东西,所以它的承诺(async函数总是返回一个承诺)将undefined在它解决时解决错误消息清楚地表明您正在尝试直接呈现承诺
getData返回,而不是等待它解决然后呈现分辨率
Addressing #1: getDatashould returnthe result of calling json:
解决 #1:getData应该返回调用的结果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
地址 #2:我们必须查看更多您的代码,但从根本上说,您不能这样做
<SomeElement>{getData()}</SomeElement>
...because that doesn't wait for the resolution. You'd need instead to use getDatato set state:
...因为那不会等待决议。您需要改为使用getData来设置状态:
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 likethis:
更新:现在你已经告诉我们你的代码,你需要做的是这样的:
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 awaitin componentDidMountrather than thenand catch. You'd do that by nesting an asyncIIFE function within it and ensuring that function can't throw. (componentDidMountitself can't be async, nothing will consume that promise.) E.g.:
进一步更新:您已表示偏好使用awaitincomponentDidMount而不是thenand catch。您可以通过在其中嵌套一个asyncIIFE 函数并确保该函数不会抛出来做到这一点。(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>
);
}
}
回答by Singh
In my experience over the past few months, I've realized that the best way to achieve this is:
根据过去几个月的经验,我意识到实现这一目标的最佳方法是:
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>
);
}
}
If you are trying to make post request on events such as click, then call getData()function on the event and replace the content of it like so:
如果您尝试对诸如单击之类的事件发出发布请求,请在事件上调用getData()函数并像这样替换它的内容:
async getData(username, password){
const res = await axios.post('url-to-post-the-data', {
username,
password
});
...
}
Furthermore, if you are making any request when the component is about to load then simply replace async getData()with async componentDidMount()and change the render function like so:
此外,如果你做任何请求时,组件即将负载则只需更换async getData()与async componentDidMount()和改变渲染功能,如下所示:
render(){
return (
<div>{this.state.serverResponse}</div>
)
}

