TypeError:无法添加属性onload,对象不可扩展:React

时间:2019-01-27 14:23:58

标签: javascript reactjs filereader

我正在尝试在React中实现文件读取器功能,但它在 reader.onload 部分抛出了“ TypeError:无法添加属性onload,对象不可扩展”的错误。有人可以帮忙弄清楚出什么问题吗?

  handleFile = (file) => {
      const reader = new FileReader();
      reader.onload = (event) => {
          const file = event.target.result;
          const allLines = file.split(/\r\n|\n/);
          // Reading line by line
          allLines.forEach((line) => {
              console.log(line);
          });
      };
      reader.onerror = (event) => {
          alert(event.target.error.name);
      };
      reader.readAsText(file);
  }

这是我在类组件中返回的位:

    <div className="upload">
      <input
        type="file"
        id="file"
        className="input-file"
        accept=".txt"
        onChange={(e) => this.handleFile(e.target.files[0]) }
      />
    </div>

奇怪的是,代码本身可以独立工作,但不能在我的应用程序中工作。这是我的App.js:

import React, { Component } from 'react';
import './App.css';

import Layout from './components/Layout';
import Terminal from './containers/Terminal';
import Prompt from './components/Prompt'
import ChatLine from './components/ChatLine'
import Chat from './containers/Chat';

import FakeData from './components/FakeData';
import FileReader from './components/FileReader'

let optionCount = {
  a: 0,
  b: 0,
  c: 0,
  d: 0,
}

//////////////////////////////////////////////////////////////////

console.log("PLEASE FileReader.fakeDataFromReader", typeof FileReader)

class App extends Component {
  // regulates the sequence, userinput
  state = {
      userInput: '',
      userAnswer: '',
      prevSeq: 'Landing',
      currSeq: 'Landing',
      nextSeq: '',
      backontrackseq: 'Landing',
      Landing: {
        a: 'Info',
        b: 'Upload',
      },
      Info: {
        a: 'Upload',
      },
      Upload: {
        done: 'Person',
      },
      Person: {
        a: 'Ready',
        b: 'Ready',
      },
      Ready: {
        a: 'Talk',
        b: 'Person',
      },
      Talk: {
        restart: 'Landing',
      },
      Invalid: {
        start: 'Landing',
        back: ''
      },
      renderSeq: 'Landing',
      chatContent: [
        'I\'m here to talk.',
        'Blueberry Placeholder',
        'Sheme',
      ],
      optionToRender: null,
  };

  componentDidMount() {

  }
  componentWillUnmount() {

  }

  inputChangedHandler = (event) => {
    this.setState({userInput: event.target.value})
  }

  keyPressedHandler = (event) => {
    let key = event.keyCode || event.which;
    if (key === 13){
      let userAnswer = event.target.value.toLowerCase();
      this.setState({userAnswer:userAnswer})

      // if currseq is chat, get optiontorender
      if (this.state.currSeq === 'Talk' && userAnswer !== 'restart'){
        let optionToRender = this.chatOptionHandler(userAnswer)
        // this.setState({optionToRender: optionToRender})

        // set state here!
        let addToChatContent = this.updateChatContent(optionToRender) // this is a new chosen line to add

        this.setState({
          optionToRender: optionToRender,
          chatContent: [...this.state.chatContent, addToChatContent]
        })

      } else { // otherwise render seq
        let seqToRender = this.resHandler(userAnswer)
        this.setState({renderSeq: seqToRender})
      }
      // empty the input field
      this.setState({userInput: ''})
    }
  }

  chatOptionHandler = (res) => {
    let choice = ''
    switch (res) {
      case 'give me a shout.':
        choice = "a";
        // also need to add this to the chatContent?
        break;
      case 'what?':
        choice = "b";
        break;
      case 'but why?':
        choice = "c";
        break;
      case 'tell me.':
        choice = "d";
        break;
      default:
        choice = null;
    }
    return choice
  }

  // input: option from the user
  // output: random line from the data object
  updateChatContent = (opt) => {
    try {
      let selectedLine;
      if (optionCount[opt] <= FakeData.response[opt].length - 1){
        selectedLine = FakeData.response[opt][optionCount[opt]]
        optionCount[opt] += 1
      } else {
        optionCount[opt] = 0
        selectedLine = FakeData.response[opt][optionCount[opt]]
      }
      return selectedLine;
    }
    catch(error) {
      console.error(error);
      return 'line blackhole'
    }
  }

  resHandler = (res) => {
    let currSeq = this.state.currSeq
    let nextSeq = this.state[currSeq][res]

    // valid next sequence was found
    if (nextSeq){
      this.setState({
        prevSeq: currSeq,
        currSeq: nextSeq,
        renderSeq: nextSeq
      })
      return nextSeq

    } else { // invalid, there is no nextseq according to the input
      // if the currea is 'invalid', render backontrackseq
      if (currSeq === 'Invalid'){
        return 'Invalid'
      } else { // if the currseq is not 'invalid', render Invalid
        this.setState({
          backontrackseq: currSeq,
          Invalid: {
            start: 'Landing',
            back: currSeq,
          },
          prevSeq: currSeq,
          currSeq: 'Invalid',
          renderSeq: 'Invalid'
        })
        return 'Invalid'
      }
    }
  }

  handleFile = (file) => {
      const reader = new FileReader();
      reader.onload = (event) => {
          const file = event.target.result;
          const allLines = file.split(/\r\n|\n/);
          // Reading line by line
          allLines.forEach((line) => {
              // IMLEMENT
              // from text, get patterns and write it in a json format
              console.log(line);
          });
      };
      reader.onerror = (event) => {
          alert(event.target.error.name);
      };
      reader.readAsText(file);
  }


  handleFile = (file) => {
      const reader = new FileReader();
      reader.onload = (event) => {
          const file = event.target.result;
          const allLines = file.split(/\r\n|\n/);
          // Reading line by line
          allLines.forEach((line) => {
              console.log(line);
          });
      };
      reader.onerror = (event) => {
          alert(event.target.error.name);
      };
      reader.readAsText(file);
  }

  render() {
    console.log("[APP] this.state.currSeq:",this.state.currSeq)
    let optionToRender = this.state.optionToRender
    console.log("[APP] optionToRender", optionToRender)

    let chatContentAll = this.state.chatContent

    // render line by line
    let chatLineComp = chatContentAll.map((line, i) => {
      return <ChatLine key={i} lineContent = {line}/>
    })

    return (
      <div className="App">
        <Layout>
          {this.state.currSeq === 'Upload'?
          <Terminal sequence={this.state.renderSeq}>

            <div className="upload">
              <input
                type="file"
                id="file"
                className="input-file"
                accept=".txt"
                onChange={(e) => this.handleFile(e.target.files[0])}
              />
            </div>

            <Prompt userInput = {this.state.userInput}/>
            <input
              type="text"
              onChange={this.inputChangedHandler}
              onKeyPress={this.keyPressedHandler}
              value={this.state.userInput} />
          </Terminal>
          :
          <Terminal sequence={this.state.renderSeq}>
            <Prompt userInput = {this.state.userInput}/>
            <input
              type="text"
              onChange={this.inputChangedHandler}
              onKeyPress={this.keyPressedHandler}
              value={this.state.userInput} />
          </Terminal>
        }

          <Chat
            choice={this.state.userAnswer}
            optionToRender={this.state.optionToRender}
            content={this.state.chatContent}>
            {chatLineComp}
          </Chat>

        </Layout>
      </div>
    );
  }
}

export default App;

0 个答案:

没有答案