简体   繁体   中英

javascript async in react.js

In a java-script file, I have this code:

import axios from "axios";
let baseUrl = "http://localhost:8080";

export async function getData(parameter) {
    let url=baseUrl.concat(parameter);
    axios.get(url)
        .then(function (response) {
            console.log(response.data);
            return response.data;
        })
        .catch(function (error) {
            console.log("accessing " + url+ " got error : " +error);
        });
}

And in my User class, I wrote this :


class Users extends React.Component{

    state={
        userList:''
    };

    componentWillMount() {
        this.setState(
            (prevState,props)=>{
                return {userList:await StaticData.getData("/users")};
            }
        );
        console.log(this.state.userList);
    }

    render() {
        return(
            <div>
                {this.state.userList}
            </div>
        );
    }
}
export default Users;

CodeSandBoxing won't work as I'm using local host.

First of all this gives me a error saying - await only for async function, which it is already, then what is the erro

And secondly, if I remove the await, why new userData is not being rendered?

I'm sorry but we have many errors and misconception we need to update here in order to solve this.

First the await in your function won't work because you didn't mark the function that use the await keyword to be async function. so you should do it like

    componentWillMount() {
        this.setState(
            async (prevState,props)=>{
                return {userList:await StaticData.getData("/users")};
            }
        );
        console.log(this.state.userList);
    }

But this solve the error about await and it won't solve your original problem which is why the data is not rendered...?

you need to know that the async logic of calling http using a promise is different from normal sync code where you execute the commands from top to bottom, left to right.

when you user a promise you tell your program that something gonna happen in an async manner here which mean we don't know when exactly is gonna return the result.

here is an example

console.log('a');
axios.get('some url...').then( () => console.log('b') );
console.log('c');

the result of these three commands is

a
c
b

now looking at your problem, first you have to return the axios promise in your function like and it doesn't need to be async because it is not using the keyword await inside it

export function getData(parameter) {
    let url=baseUrl.concat(parameter);
    return axios.get(url)
        .then(function (response) {
            console.log(response.data);
            return response.data;
        })
        .catch(function (error) {
            console.log("accessing " + url+ " got error : " +error);
        });
}

finally if the return value in response.data is an array you cannot render it as it's in React. instead use the map function in jsx like

<div>
 { this.state.userList.map(user => <div key={user.id}> { user.name } </div>) }
</div>

and I recommend you put the fetch data logic in componentDidMount instead of

first, you should return the promise: return axios.get(url) ....

First of all this gives me a error saying - await only for async function, which it is already, then what is the erro

you are using arrow function so it must have the async identifier:

componentWillMount() {
    this.setState(
        async (prevState,props)=>{
            return {userList:await StaticData.getData("/users")};
        }
    );
    console.log(this.state.userList);
}

And, lastly, the best place to fetch data is in componentDidMount .

Lot of conceptual flaws in your code.

  1. Component will mount is deprecated. Use componentDidMount() instead.
  2. Either use async await inside your getData function or use then and catch.
export async function getData(parameter) {
    let url= baseUrl.concat(parameter);
    try{
        const response = await axios.get(url);
    } catch (err) {
        console.log("accessing " + url+ " got error : " +err);
    }
}

To use Promise then catch replace your code with

export function getData(parameter) {
let url=baseUrl.concat(parameter);
return axios.get(url)
    .then(function (response) {
        console.log(response.data);
        return response.data;
    })
    .catch(function (error) {
        console.log("accessing " + url+ " got error : " +error);
    });

}

Also since you are using an arrow function, await can only be inside an async function. so

this.setState(
       async (prevState,props)=>{
            return {userList:await StaticData.getData("/users")};
        }
    );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM