我的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
进行计算和显示?
答案 0 :(得分:1)
好的一面是分辨率很简单。归功于@Jaxx。
在if (this.state.type[i] === 'Expenses')
调用中从if (this.state.type[i] === 'Expense')
更改为map()
的问题。