I have one strange problem by uploading files using React JS.
The main component is as follows:
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'));
There is more code but this is the important one.
And FileInputButton component is as follows:
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>
);
};
Everything works fine. There is only one scenario when it doesn't work as expected.
If the file is chosen little remove button (the removeButton from FileInputButton component) is shown. If I click on it the removeFilefunction from main component gets called, and I change the state (find that file in state, remove it, and add a new object with initial values for that file and then update the state).
The file is removed and everything works fine. If I new add a new file, that works also as expected. The problem is if I try to add the same file again, then it doesn't work. The handleFiles function isn't called at all.
If I add first file and then remove it, then add new second file then remove the second file and then again add the first file it works fine.
Only problem is if I add first file, then remove it and then try to add it again it doesn't work. I do not get any errors in console.
Any idea what I do wrong?