React-在获取数据后设置状态时渲染HTML

时间:2018-10-09 11:38:20

标签: javascript reactjs

我有一个需要从Stripe API(付款处理器)中提取发票数据的应用程序。返回发票数据后,我正在尝试使用this.setState({invoiceData: invoices})更新状态,其中invoices是从Stripe API返回的数据中构建的HTML字符串。

问题在于HTML未被呈现,而是显示为纯文本。我对React很陌生,只是对渲染状态一无所知,但是现在我很想解决这个问题。我需要做什么来呈现HTML?请在下面查看我的代码。

import React from 'react';

class BillingInvoices extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            invoiceData: false
        }
    }

    // When the 'BillingInvoices' component is mounted:
    componentDidMount() {

        // Get invoice data from Stripe API.
        fetch('/stripe-invoices', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                customerId: '128973982'
            })
        })
        .then((response) => {
            if (response.ok) {
                return response.json();
            } else {
                console.log('Error with Stripe response');
            }
        })
        .then((stripeData) => {

            var invoiceCount = stripeData['result']['data'].length;
            var i;
            var invoices = '';

            for (i = 0; i < invoiceCount; i++) {
                invoices += '<div><a href="' + stripeData['result']['data'][i]['invoice_pdf'] + '" download>' + stripeData['result']['data'][i]['number'] + '</a></div>';
            }

            this.setState({
                invoiceData: invoices
            })
        })
        .catch((error) => {
            console.log('Error: ', error);
        });
    }

    render() {
        return (
            <div id="billing-invoices">
                {this.state.invoiceData ? this.state.invoiceData : null}
            </div>
        );
    }
}

export default BillingInvoices;

谢谢您的见解。

3 个答案:

答案 0 :(得分:1)

您可以像这样使用JSX向invoiceData填充react组件:

let invoices = (<div>{stripeData['result']['data'].map(data => (<div><a href={data['invoice_pdf']}  download>{data['number']}</a></div>))}</div>);

this.setState({invoiceData: invoices});

您可以使用上面的内容替换第二个then子句的内容,而其余代码保持不变。

答案 1 :(得分:1)

我为示例删除了一些代码,以使其更易于阅读:

class BillingInvoices extends React.Component {

  constructor(props) {
    super(props);
    this.state = { invoiceData: [] }
  }

  componentDidMount() {
    fetch('/stripe-invoices')
      .then((response) => response.ok && response.json())

      // Here I'm assigning the nested array to `invoiceData` immediately
      // so that you don't need to map over it later
      .then((data) => this.setState({ invoiceData:  data.result.data }));
  }

  render() {

    // Here we can check if the data exists. If it doesn't
    // show a loading icon (or something) until it is
    if (!this.state.invoiceData) <Loader />

    // ...otherwise show the data
    return (
      <div id="billing-invoices">

        // we map over the invoice data and for each invoice
        // return JSX (your div with an anchor populated with that invoice data)
        {this.state.invoiceData.map((invoice) => {
          return (
            <div>
              <a href={invoice.invoice_pdf} download>{invoice.number}</a>
            </div>
          )
        })}
      );
      </div>
    )
  }
}

答案 2 :(得分:0)

将结果json置于组件状态是一个好主意。

但是,然后,您应该使用JSX的功能直接在渲染方法中处理此json。

检查official documentation有关如何使用JSX的信息。

这是一个使用JSX时您的组件看起来像的虚拟示例:

import React from "react";

class BillingInvoices extends React.Component {
  constructor(props) {
    super(props);
  }

  state = {
    invoices: []
  }

  // When the 'BillingInvoices' component is mounted:
  componentDidMount() {
    // Get invoice data from Stripe API.
    fetch("/stripe-invoices", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        customerId: "128973982"
      })
    })
      .then(response => {
        if (response.ok) {
          this.setState(invoices: response.json());
        } else {
          console.log("Error with Stripe response");
        }
      })
      .catch(error => {
        console.log("Error: ", error);
      });
  }

  render() {
    return (
      <div id="billing-invoices">
        {this.state.invoices.map((invoice, index) => {
          return (
            <div key={index}>{invoice.name}</div>
          )
        })}
      </div>
    );
  }
}

export default BillingInvoices;