2017-11-24 3 views
0

Ich habe ein seltsames Problem durch Hochladen von Dateien mit React JS.Hochladen von Dateien in React JS

Die Hauptkomponente ist wie folgt:

class Test extends React.Component { 
     constructor(props){ 
     super(props); 

     this.state = { 
      files: [ 
       {file_type: registrationFormFields.ID_CARD.key, values: {active: false, fileName: language.btnIdCard, file: null, base64: ""}}, 
       {file_type: registrationFormFields.STATUTES.key, values: {active: false, fileName: language.btnStatut, file: null, base64: ""}}, 
       {file_type: registrationFormFields.BLANK_LETTER_HEAD.key, values: {active: false, fileName: language.btnBlanco, file: null, base64: ""}}, 
       {file_type: registrationFormFields.COMPANY_PHOTO.key, values: {active: false, fileName: language.btnCompanyPhoto, file: null, base64: ""}} 
      ] 
     }; 
    } 


    handleFiles(file_type, event){ 
     event.preventDefault(); 
     let self = this; 
     let fileValue = event.target.value; 
     let files = ""; 


     let file = event.target.files[0]; 
     let filename = file.name.substr(0, file.name.lastIndexOf('.')) || file.name; 
     const size_in_mb = file ? file.size/1000000 : null; 


     if(this.fileIsValid(file_type, size_in_mb)){ 
      if(fileValue){ 
       this.getBase64(file, function(e){ 
        let base64 = e.target.result; 
        let nState = self.state.files; 

        if(self.state.files.some(i => i.file_type === file_type)) 
         nState = self.state.files.filter(f => f.file_type !== file_type); 

        files = [...nState, {file_type: file_type, values: {active: true, fileName: filename, file, base64: base64}}]; 

        self.setState({files: files}); 
       }); 

      } 
     } 
    } 

    removeFile = (file_type, file_name) => { 
     let nState = this.state.files; 
     let nFiles = this.state.files; 

     if(this.state.files.some(i => i.file_type === file_type)){ 
      nState = this.state.files.filter(f => f.file_type !== file_type); 
      nFiles = [...nState, {file_type: file_type, values: {active: false, fileName: file_name, file: null, base64: ""}}]; 

     } 
     this.setState({files: nFiles}); 
    }; 

    render(){ 
     return (
     <FileInputButton pictureIcon="credit-card" 
         onFileChange={this.handleFiles.bind(this, registrationFormFields.ID_CARD.key)} 
         btnName="idCard" 
         extraClass="col-lg-offset-2 col-md-offset-2 col-sm-offset-2" 
         fileType={registrationFormFields.ID_CARD.key} 
         fileName={language.btnIdCard} 
         removeFile={this.removeFile} 
         errors={this.state.errors[registrationFormFields.ID_CARD.key]} 
         values={this.getValues(registrationFormFields.ID_CARD.key)}/> 
    ) 
    } 
} 

React.render(<Test />, document.getElementById('container')); 

Es gibt mehr Code, aber dies ist das sehr wichtig.

Und FileInputButton Komponente ist wie folgt:

const FileInputButton = ({extraClass, pictureIcon, btnName, onFileChange, values, removeFile, fileType, fileName, errors}) => { 

    const name = values.fileName === fileName ? `Add ${fileName}` : `Added ${fileName}`; 
    const icon = values.active ? "check" : "upload"; 

    let borderClass = ""; 
    if(values.active) borderClass = "fileSuccess"; 
    if(errors) borderClass = "fileError"; 


    let removeButton = ""; 
    if(values.active){ 
     removeButton = <div className="remove-file" onClick={() => removeFile(fileType, fileName)}><Ionicon icon="ios-close" fontSize="22px" color={styles.errorColor}/> Remove</div> 
    } 

    let added_file = ""; 
    if(values.active){ 
     added_file = <div className="added-file-name"><Ionicon icon="ios-checkmark" fontSize="22px" color={styles.successColor}/>{values.file.name}</div> 
    } 

    return (
     <div className={`col-lg-4 col-md-4 col-sm-4 ${extraClass}`}> 
      <div className="picture-container" style={{marginLeft: 18}}> 
       <div className={`picture ${borderClass}`}> 
        <FontAwesome name={pictureIcon} size="3x" className="picture-src"/> 
       </div> 
      </div> 

      <div className="uploadButtonBox" style={{width: '100%', textAlign: 'center', marginTop: 20}}> 
       <label className={`fileUploadButton ${borderClass}`}> 
        <FontAwesome name={icon} className="faIcon" style={{height: '39px !important'}}/> 
        <span className={`btnFileText ${btnName}`}>{name}</span> 
        <input id="btnFile" type="file" style={{display: 'none'}} onChange={onFileChange} name={name}/> 
       </label> 
      </div> 
      {added_file} 
      {removeButton} 
      <div className="errorBox">{errors}</div> 
     </div> 
    ); 
}; 

Alles funktioniert gut. Es gibt nur ein Szenario, wenn es nicht wie erwartet funktioniert.

Wenn die Datei ausgewählt ist, wird die Schaltfläche remove (die removeButton von FileInputButton Komponente) angezeigt. Wenn ich darauf klicke, wird die removeFile-Funktion von der Hauptkomponente aufgerufen, und ich ändere den Status (finde diese Datei im Status, entferne sie und füge ein neues Objekt mit Anfangswerten für diese Datei hinzu und aktualisiere dann den Status).

Die Datei wird entfernt und alles funktioniert einwandfrei. Wenn ich neu eine neue Datei hinzufügen, funktioniert das auch wie erwartet. Das Problem ist, wenn ich versuche, die gleiche Datei erneut hinzuzufügen, dann funktioniert es nicht. Die handleFiles Funktion wird überhaupt nicht aufgerufen.

Wenn ich die erste Datei hinzufügen und entfernen Sie sie dann, fügen Sie neue zweite Datei dann entfernen Sie die zweite Datei und fügen Sie dann erneut die erste Datei es funktioniert gut.

Nur Problem ist, wenn ich die erste Datei hinzufügen, dann entfernen und dann versuchen, es erneut hinzuzufügen, funktioniert es nicht. Ich bekomme keine Fehler in der Konsole.

Irgendeine Idee, was ich falsch mache?

Antwort

2

Sie haben den onChange-Handler bei der Dateieingabe. Wenn Sie die Datei jedoch aus Ihrem Status löschen, löschen Sie sie nicht von Ihrer Eingabe. Wenn Sie also versuchen, dieselbe Datei erneut hochzuladen, wird das Ereignis onChange nicht ausgelöst. Daher wird Ihr Handler nicht aufgerufen.

Setzen Sie den Wert Ihrer Eingabedatei auf '', um ihn zurückzusetzen.

Nehmen wir an, dass Ihr Lösch-Handler so aussehen würde.

handleDelete(){ 
    document.querySelector('input[type=file]').value = ''; 
    this.props.removeFile(this.props.fileType, this.props.fileName); 
} 

Dieser Code ist möglicherweise nicht ganz im Sinne Ihres Codes, aber Sie werden den Punkt verstehen.

+0

Und wie man es löst? – Boky

+0

Überprüfen Sie die aktualisierte Antwort –

+0

Natürlich. Vielen Dank. – Boky