node.js - ReactJS : Async function with axios call makes axios call in componentDidUpdate to return promise

标签 node.js reactjs axios

我的组件代码如下:

import React, { Component } from 'react';
import axios from 'axios';
import "bootstrap/dist/css/bootstrap.min.css";
import {
    Table
} from 'reactstrap';

const Adhoc = async (props) => {
  let cost = await props.cost(props.adhoc._id)

  return(
    <tr>
      <td>{props.adhoc.jIssue}</td>
      <td>{props.adhoc.paid ? "Paid" : "Not paid"}</td>
      <td>APP{props.adhoc.sprint}</td>
      <td>£{cost.data[0]}</td>
    </tr>
  )}

export default class QAdhocsDisplay extends Component { 
    constructor(props) {
        super(props);

    this.costingAdhoc = this.costingAdhoc.bind(this)

    this.state = {
      adhocs: []
    };
}

componentDidMount() {
    axios.get('http://localhost:5000/adhocs/retrieve')
      .then(response => {
        this.setState({ adhocs: response.data })
      })
      .catch((error) => {
        console.log(error);
      })
}

async costingAdhoc(id) {
  const data = await axios.get('http://localhost:5000/jira/issue/' + id)
      .catch((error) => {
        console.log(error);
      })

  return data;


}

adhocsList() {
    return this.state.adhocs.map(currentadhoc=> {
      return <Adhoc adhoc={currentadhoc} cost={this.costingAdhoc} key={currentadhoc._id}/>;
    })
  }

render(){
    return (
      <div className="toborder" style = {{paddingBottom: "59px"}}>
              <div className="display" style ={{backgroundColor: "#5394b2"}}>
                <h5 style = {{padding:"13px"}}>Adhoc status</h5>
                </div>
                <div className="table">
                <Table size="sm" bordered striped>
                <thead className="thead-light">
                    <tr className="adhocs">
                    <th className="sticky-column medium" >Adhoc issue</th>
                    <th className="sticky-column medium" >Payment status</th>
                    <th className="sticky-column medium" >Sprint</th>
                    <th className="sticky-column medium" >Projected cost</th>
                    </tr>
                </thead>
                <tbody>
                    { this.adhocsList() }
                </tbody>
                </Table>
                </div>
            </div>
    )}

}

我的问题是我有函数costingAdhoc(id),我将其作为 Prop 传递给子组件Adhoc。为了能够从 axios 调用访问信息,我需要这两个函数都是异步的。

将为处于将在函数 adhocsList() 中映射的状态中的每个项目呈现 Adhoc 类型的子组件。由于某种原因,这会导致 componentDidUpdate() 中的 axios 调用抛出此错误:

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

错误指向我设置状态的行。这意味着 costingAdhoc(id) 函数的异步性质导致我在 componentDidUpdate() 函数中的 axios 调用仅返回 promise ,而不返回实际数据。

最佳答案

您的问题是您将其声明为子组件的Adhoc组件实际上是一个 promise 。 为什么? 声明为 async 的函数默认返回 Promise,因此即使您返回:

<tr>
      <td>{props.adhoc.jIssue}</td>
      <td>{props.adhoc.paid ? "Paid" : "Not paid"}</td>
      <td>APP{props.adhoc.sprint}</td>
      <td>£{cost.data[0]}</td>
</tr>

您实际上是将其包裹在 promise 中返回。 React 组件不能成为 promise 。

关于node.js - ReactJS : Async function with axios call makes axios call in componentDidUpdate to return promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59093403/

相关文章:

javascript - 更改 axios header 中的 Content-Type 以修复 415 错误

javascript - 使用 vue 作为前端从后端 laravel 下载文件

node.js - 在Socket.IO中, 'heartbeat'是可以用来触发其他 Action 的事件吗?

javascript - 折叠时更改 bootstrap-accordion 的超时

javascript - 在 React App 中使用 Axios 将响应数据下载为流

javascript - 可重用组件来等待数据

javascript - 在 redux 操作中使用 socketio

node.js - 在 Gulp 文件中以编程方式获取 BrowserSync 外部 URL,以便我可以将其传递给外部 Node 脚本?

node.js - Node.io、JSDOM 还是 PhantomJs?或者,YQL-data.html.cssselect?

node.js - 是否有可能在MongoDB中删除 "join"文档并删除 "parent"文档但仍然保留 "child"文档?