【问题标题】:javascript async in react.jsreact.js中的javascript异步
【发布时间】:2019-12-12 10:50:41
【问题描述】:

在 java 脚本文件中,我有以下代码:

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

在我的用户类中,我写了这个:


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 无法工作,因为我使用的是本地主机。

首先,这给了我一个错误提示 - await only for async function,它已经是,然后是什么错误

其次,如果我删除了等待,为什么没有呈现新的 userData?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您的代码中有很多概念性缺陷。

    1. 不推荐使用将安装的组件。请改用 componentDidMount()。
    2. 要么在 getData 函数中使用 async await,要么使用 then 和 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);
        }
    }
    

    要使用 Promise,然后用

    替换您的代码
    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);
        });
    

    }

    此外,由于您使用的是箭头函数,因此 await 只能在异步函数内。所以

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

    【讨论】:

      【解决方案2】:

      首先,您应该返回承诺: return axios.get(url) ....

      首先,这给了我一个错误提示 - 仅等待异步 函数,它已经是,那么错误是什么

      您正在使用箭头函数,因此它必须具有异步标识符:

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

      最后,获取数据的最佳位置是componentDidMount

      【讨论】:

      • 现在我在 componentDidMount 中使用它,但它让我在渲染中注意到。
      【解决方案3】:

      很抱歉,我们有许多错误和误解,需要在此处更新以解决此问题。

      首先,函数中的await 不起作用,因为您没有将使用await 关键字的函数标记为async 函数。所以你应该这样做

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

      但这解决了关于await 的错误,它不会解决你原来的问题,这就是为什么没有呈现数据...?

      您需要知道,使用 promise 调用 http 的异步逻辑与从上到下、从左到右执行命令的普通同步代码不同。

      当你使用一个 promise 时,你告诉你的程序这里会以异步方式发生一些事情,这意味着我们不知道什么时候会返回结果。

      这是一个例子

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

      这三个命令的结果是

      a
      c
      b
      

      现在看看你的问题,首先你必须在你的函数中返回 axios 承诺,它不需要是异步的,因为它没有在其中使用关键字 await

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

      最后,如果response.data 中的返回值是一个数组,你就不能像在 React 中那样渲染它。而是使用jsx 中的map 函数,就像

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

      我建议您将获取数据逻辑放在 componentDidMount 而不是

      【讨论】:

      • 错误 - await 只能在 async 函数中使用,警告 - componentWillMount 应该是 void 类型
      • 哦,对不起async 应该用于在componentWillMount 中不使用等待的容器功能@ 对不起.. 我的错误。我会编辑答案。
      猜你喜欢
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      • 2012-01-02
      • 2021-03-21
      • 2012-06-16
      • 1970-01-01
      • 2019-03-26
      • 1970-01-01
      相关资源
      最近更新 更多