2017-11-24 10 views
0

React JSを使用してファイルをアップロードすると、奇妙な問題が発生します。次のようにReact JSでファイルをアップロード

主成分は次のとおりです。

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')); 

あり多くのコードがあるが、これは重要なものです。次のように

そしてFileInputButtonコンポーネントは次のとおりです。

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> 
    ); 
}; 

すべてが正常に動作します。期待どおりに動作しないシナリオは1つだけです。

ファイルを選択した場合、removeボタン(FileInputButtonコンポーネントからのremoveButton)はほとんど表示されません。私がそれをクリックすると、メインコンポーネントのremoveFile関数が呼び出され、状態を変更します(そのファイルを状態で見つけて削除し、そのファイルの初期値を持つ新しいオブジェクトを追加してからを更新します)。

ファイルが削除され、すべて正常に動作します。新しいファイルを追加すると、期待どおりに動作します。問題は、同じファイルをもう一度追加しようとすると、になりません。 handleFiles関数はまったく呼び出されません。

最初のファイルを追加して削除した場合は、新しい2番目のファイルを追加して2番目のファイルを削除し、最初のファイルをもう一度追加してください。

最初のファイルを追加してから削除してから、もう一度追加しようとすると問題はありません。私はコンソールに何のエラーもありません。

私は間違っていると思いますか?

答えて

2

あなたのファイル入力にonChangeハンドラがありますが、あなたの状態からファイルをクリアすると、入力からクリアされません。したがって、同じファイルを再度アップロードしようとすると、onChangeイベントはトリガされないため、ハンドラは呼び出されません。

入力ファイルの値を ''に設定してリセットします。

削除ハンドラは次のようになります。

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

このコードは完全にあなたのコードの精神ではないかもしれませんが、その点が分かります。

+0

どうすれば解決できますか? – Boky

+0

更新された回答を確認 –

+0

もちろん。ありがとう。 – Boky

関連する問題