如果在map()内部,则无法使用

时间:2019-02-10 13:47:50

标签: javascript reactjs

我的React组件允许顺序上传文本文件以在页面上显示其内容。内容正在累积到componentWillReceiveProps(nextProps)调用内的状态。该调用中的各种键是来自上载文本文件的键。

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { getFile } from '../actions/fileActions';
import toJsonArray from '../utils/toJsonArray';

class TableInput extends Component {
  constructor() {
    super();

    this.state = {
      file: {},
      'Incurred Date': [],
      'Memo': [],
      'Person Name': [],
      'Amount': [],
      'Billable': [],
      'Entry Date': [],
      'Comment': [],
      type: [],
      length: 0
    };

    this.onFileUpload = this.onFileUpload.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    console.log('nextProps:', nextProps);

    const { file } = nextProps.file;

    if (file) {
      this.setState({ file });
    }

    if (file) {
      let readFromFile;

      const reader = new FileReader();
      reader.onload = event => {
        readFromFile = event.target.result;

        const jsonArray = toJsonArray(readFromFile);

        this.setState({
          'Incurred Date': this.state['Incurred Date'].concat(jsonArray.map(item => item['Incurred Date'])),
          'Memo': this.state['Memo'].concat(jsonArray.map(item => item['Memo'])),
          'Person Name': this.state['Person Name'].concat(jsonArray.map(item => item['Person Name'])),
          'Amount': this.state['Amount'].concat(jsonArray.map(item => item['Amount'])),
          'Billable': this.state['Billable'].concat(jsonArray.map(item => item['Billable'])),
          'Entry Date': this.state['Entry Date'].concat(jsonArray.map(item => item['Entry Date'])),
          'Comment': this.state['Comment'].concat(jsonArray.map(item => item['Comment'])),
          length: this.state.length + jsonArray.length,
          type: this.state.type.concat(Array(jsonArray.length).fill(file.name === 'expenses.csv' ? 'Expense' : 'Time'))
        });
      };

      reader.onerror = error => console.log(error);
      reader.readAsText(file);
    }
  }

  onFileUpload() {
    const file = document.querySelector('input[type=file]').files[0];

    this.props.getFile(file);
  }

  render() {
    let rows = [];

    if (this.state.length) {
      for (let i = 0; i < this.state.length; i++) {
        rows.push(
          <tr key={i}>
            <td>{this.state['Person Name'] && this.state['Person Name'][i]}</td>
            <td>{this.state['Amount'] && this.state['Amount'][i]}</td>
            {this.state['Memo'] && this.state['Memo'][i] && <td>{this.state['Memo'][i]}</td>}
            {this.state['Comment'] && this.state['Comment'][i] && <td>{this.state['Comment'][i]}</td>}
            {this.state['Incurred Date'] && this.state['Incurred Date'][i] && <td>{this.state['Incurred Date'][i]}</td>}
            {this.state['Entry Date'] && this.state['Entry Date'][i] && <td>{this.state['Entry Date'][i]}</td>}
            <td>{this.state['Billable'] && this.state['Billable'][i]}</td>
            <td>{this.state.type && this.state.type[i]}</td>
          </tr>
        )
      }
    }

    let totalAmountExpense = this.state['Amount'] && this.state['Amount'].map((item, i) => {
      let total = 0;
      if (this.state.type[i] === 'Expenses') {
        total += parseInt(this.state['Amount'][i], 10);
      }

      return total;
    }).reduce((total, num) => parseInt(total, 10) + parseInt(num, 10), 0);

    const totalAmount = this.state['Amount'] && this.state['Amount'].reduce((total, num) => parseInt(total, 10) + parseInt(num, 10), 0);

    return (
      <div>
        <table className='table-input'>
          <thead>
            <tr>
              <th>Name</th>
              <th>Amount</th>
              <th>Description</th>
              <th>Date</th>
              <th>Billable</th>
              <th>Type</th>
            </tr>
          </thead>
          <tbody>
            {rows}
          </tbody>
        </table>
        <p>Total Amount: {totalAmount}</p>
        <p>Total Amount for Expense: {totalAmountExpense}</p>
        <label htmlFor='files' className='file-input-label'>Select File</label>
        <input type='file' id='files' className='file-input-hidden' onChange={this.onFileUpload} />
      </div>
    );
  }
}

const mapStateToProps = state => ({
  file: state.file
});

export default connect(mapStateToProps, { getFile })(TableInput);
计算

const totalAmount并显示确定。 let totalAmountExpense不是。似乎未调用if内部的map()调用。 totalAmountExpense应该计算类型Expense的总金额。

如何获取totalAmountExpense进行计算和显示?

1 个答案:

答案 0 :(得分:1)

好的一面是分辨率很简单。归功于@Jaxx。

if (this.state.type[i] === 'Expenses')调用中从if (this.state.type[i] === 'Expense')更改为map()的问题。