反应-使状态和变量不同步

时间:2018-07-06 06:44:07

标签: javascript reactjs frontend

我有一个“反应表”,每一行都是一个子组件。在每种情况下,我都从后端获取一些数据,并尝试在列中求和。 代码:

import React, { Component } from 'react'
import {getBillingSpecificationDetails} from '../../routes/BillingDashboard/BillingDashboardApi'
import './table.css'

const cols = [{
  label: '',
  key: 'transactionType'
}, {
  label: 'Currency',
  key: 'feeCurrency'
}, {
  label: 'Units',
  key: 'units'
}, {
  label: 'Unit Price',
  key: 'unitPrice'
}, {
  label: 'Net Amount',
  key: 'netAmount'
}, {
  label: 'VAT Rate',
  key: 'vatRate'
}, {
  label: 'VAT Amount',
  key: 'vatAmount'
}, {
  label: 'Gross Amount',
  key: 'grossAmount'
}]

let total = {
  transactionType: 'TOTAL',
  feeCurrency: '',
  units: 0,
  unitPrice: 0,
  netAmount: 0,
  vatRate: 0,
  vatAmount: 0,
  grossAmount: 0
}

class DetailsTable extends Component {

  state = {
    data: null
  }

  componentDidMount() {
    getBillingSpecificationDetails(this.props.billingRefNumber)
      .then((data) => this.setState({
        data
      }))
      .catch(err => console.log(err))
  }

  generateHeaders(headers) {
    return <tr>
      {headers.map(colData => {
        return <th key={colData.key}> {colData.label} </th>
      })}
    </tr>
  }

  generateRows(headers, data) {

    let monthlyFees = data.specificationDetailsInfoList.map(item => {
      item.transactionType = item.transactionType.replace(/\_+/g, ' ')
      let cells = headers.map(colData => {
        total[colData.key] += isNaN(item[colData.key]) ? '' : item[colData.key]
        return <td key={colData.key}>{item[colData.key]}</td>
      })
      return <tr key={item.transactionType}>{cells}</tr>
    })
    let shops = data.specificationDetailsGroupList.map(groupHeader => {
      let header = <tr><td style={{ backgroundColor: 'lightgrey' }} key={groupHeader.particulars} colSpan="8">{groupHeader.particulars}</td></tr>
      let shopData = groupHeader.specificationDetails.map(item => {
        let cells = headers.map(colData => {
          total[colData.key] += isNaN(item[colData.key]) ? '' : item[colData.key]
          return <td key={colData.key}>{item[colData.key]}</td>
        })
        return <tr key={item.id}>{cells}</tr>
      })
      return [header].concat(shopData)
    })
    let cells = headers.map(colData => {
      return <td style={{ backgroundColor: 'lightgrey' }} key={colData.key}>{total[colData.key]}</td>
    })
    let totalRow = <tr key="total">{cells}</tr>
    return [].concat(monthlyFees, shops, totalRow)
  }

  render() {
    return (
      <table style={{ borderCollapse : 'collapse' }}>
        <thead>
        {this.generateHeaders(cols)}
        </thead>
        {this.state.data &&
          <tbody>
            {this.generateRows(cols, this.state.data)}
          </tbody>
        }
      </table>
    )
  }

}

export default DetailsTable

所以我首先构造列。 然后在“ componentDidMount”上,我从服务器获取数据并设置状态。

服务器的响应: https://jsonformatter.org/33dc3d

然后在渲染中,我调用了两个方法:

'generateHeaders':映射通过'cols'标签并返回每个标签的'td'元素

和'generateRows'仅在后端有数据时才调用。它映射响应中的第一个数组(让每月费用= ...),并为每个项目生成“ tr”和“ td's”。还将金额加到总额中。商店也一样。

现在我必须做一个“总计”行。每个td汇总该列中的所有项目。 当我渲染了一个DetailsTable时,它工作正常,但是就像我说的那样,这只是另一张表的子组件(我使用React Table库)。 因此,每个渲染的对象也都添加到他之前的对象中。 我尝试对方法中的setState进行操作,但是它得到了循环调用,并且崩溃了。

0 个答案:

没有答案