Reactjs 如何在render()中处理更新的组件状态?
这是一个允许文本文件上传的React组件。文件内容稍后将显示在组件中Reactjs 如何在render()中处理更新的组件状态?,reactjs,Reactjs,这是一个允许文本文件上传的React组件。文件内容稍后将显示在组件中 import React, { Component } from 'react'; import { connect } from 'react-redux'; import { getFile } from '../actions/fileActions'; import toJsonArray from '../utils/toJsonArray'; class TableInput extends Component
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: {},
jsonArr: []
};
this.onFileUpload = this.onFileUpload.bind(this);
}
componentWillReceiveProps(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;
this.setState({ jsonArr: toJsonArray(readFromFile) }, () => console.log('jsonArr:', this.state.jsonArr));
};
reader.onerror = error => console.log(error);
reader.readAsText(file);
}
}
componentDidUpdate(_, prevState) {
if (this.state.jsonArr.length) {
console.log('this.state.jsonArr:', this.state.jsonArr);
}
}
onFileUpload() {
const file = document.querySelector('input[type=file]').files[0];
this.props.getFile(file);
}
render() {
return (
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Amount</th>
<th>Description</th>
<th>Date</th>
<th>Billable</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>TableInput</td>
<td>{this.state.file.name}</td>
<td>{this.state.jsonArr['Memo'] ? 'it exists' : 'it does not'}</td>
</tr>
</tbody>
</table>
<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);
相应的减速器:
import { FILE_UPLOAD } from '../actions/types';
const initialState = {
file: {}
};
export default function(state = initialState, action) {
switch(action.type) {
case FILE_UPLOAD:
return {
...state,
file: action.payload
};
default:
return state;
}
};
返回json数组的toJsonArray()
util方法。该数组由带有key:value
对的json对象组成
export default file => {
const strArrayFromFile = file.split('\n');
const jsonObjArray = [];
const headers = strArrayFromFile[0].split(',');
for (let i = 1; i < strArrayFromFile.length; i++) {
const data = strArrayFromFile[i].split(',');
const obj = {};
for (let j = 0; j < data.length; j++) {
obj[headers[j].trim()] = data[j].trim();
}
jsonObjArray.push(obj);
}
return jsonObjArray;
};
导出默认文件=>{
const strArrayFromFile=file.split('\n');
常量jsonObjArray=[];
const headers=strArrayFromFile[0]。拆分(',');
for(设i=1;i
解决方案是将此.setState()
应用于组件中上载文本文件中的每个键将接收props(nextrops)
。代码需要一个清理,而不是它的工作
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: {}, // as stated in the origin question not needed
jsonArr: [], // not needed either
'Incurred Date': [],
'Memo': [],
'Person Name': [],
'Amount': [],
'Billable': [],
'Entry Date': [],
'Comment': [],
length: 0,
fileName: ''
};
this.onFileUpload = this.onFileUpload.bind(this);
}
componentWillReceiveProps(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);
// various keys inside quotes below come from the uploaded file
this.setState({
'Incurred Date': jsonArray.map(item => item['Incurred Date']),
'Memo': jsonArray.map(item => item['Memo']),
'Person Name': jsonArray.map(item => item['Person Name']),
'Amount': jsonArray.map(item => item['Amount']),
'Billable': jsonArray.map(item => item['Billable']),
'Entry Date': jsonArray.map(item => item['Entry Date']),
'Comment': jsonArray.map(item => item['Comment']),
length: jsonArray.length,
fileName: file.name
});
};
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.fileName === 'expenses.csv' ? 'Expense' : 'Time'}</td>
</tr>
)
}
}
return (
<div>
<table>
<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>
<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);
import React,{Component}来自'React';
从'react redux'导入{connect};
从“../actions/fileActions”导入{getFile};
从“../utils/toJsonArray”导入到jsonarray;
类TableInput扩展组件{
构造函数(){
超级();
此.state={
文件:{},//如来源问题中所述,不需要
jsonArr:[],//也不需要
“发生日期”:[],
“备忘录”:[],
“人名”:[],
“金额”:[],
“可计费”:[],
“入职日期”:[],
“评论”:[],
长度:0,
文件名:“”
};
this.onFileUpload=this.onFileUpload.bind(this);
}
组件将接收道具(下一步){
const{file}=nextrops.file;
如果(文件){
这个.setState({file});
}
如果(文件){
让readFromFile;
const reader=new FileReader();
reader.onload=事件=>{
readFromFile=event.target.result;
const jsonArray=toJsonArray(readFromFile);
//下面引号中的各种键来自上传的文件
这是我的国家({
“发生日期”:jsonArray.map(item=>item[“发生日期”),
'Memo':jsonArray.map(item=>item['Memo']),
“人名”:jsonArray.map(item=>item['Person Name']),
'Amount':jsonArray.map(item=>item['Amount']),
'Billable':jsonArray.map(item=>item['Billable']),
“输入日期”:jsonArray.map(item=>item['Entry Date']),
'Comment':jsonArray.map(item=>item['Comment']),
长度:jsonArray.length,
文件名:file.name
});
};
reader.onerror=error=>console.log(错误);
reader.readAsText(文件);
}
}
onFileUpload(){
const file=document.querySelector('input[type=file]')。files[0];
this.props.getFile(文件);
}
render(){
让行=[];
if(this.state.length){
for(设i=0;i({
文件:state.file
});
导出默认连接(MapStateTops,{getFile})(TableInput);
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: {}, // as stated in the origin question not needed
jsonArr: [], // not needed either
'Incurred Date': [],
'Memo': [],
'Person Name': [],
'Amount': [],
'Billable': [],
'Entry Date': [],
'Comment': [],
length: 0,
fileName: ''
};
this.onFileUpload = this.onFileUpload.bind(this);
}
componentWillReceiveProps(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);
// various keys inside quotes below come from the uploaded file
this.setState({
'Incurred Date': jsonArray.map(item => item['Incurred Date']),
'Memo': jsonArray.map(item => item['Memo']),
'Person Name': jsonArray.map(item => item['Person Name']),
'Amount': jsonArray.map(item => item['Amount']),
'Billable': jsonArray.map(item => item['Billable']),
'Entry Date': jsonArray.map(item => item['Entry Date']),
'Comment': jsonArray.map(item => item['Comment']),
length: jsonArray.length,
fileName: file.name
});
};
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.fileName === 'expenses.csv' ? 'Expense' : 'Time'}</td>
</tr>
)
}
}
return (
<div>
<table>
<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>
<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);