Reactjs 如何在render()中处理更新的组件状态?

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

这是一个允许文本文件上传的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 {
  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);