Skip to content
Advertisement

Unable to render a state variable value in React Js

I’m trying to upload a file. There are some file validations performed on selecting a file. Now, I want to display a message, like “validating file, please wait!” till the function (fileChange()) in the below code gets completed.

I don’t see the message to be displayed, Can anyone please help me why is it happening ?

class FileUploaderComponent extends Component {

    constructor(props) {
        super(props);
        this.state = {
            validatingFile: false,
        }
    }

    fileChange = event => {
        this.setState({
            validatingFile: false,
        });
        if (event != undefined) {
            const inputFile = event.target.files[0];
            this.setState({
                validatingFile: true,
            });
            const fileReader = new FileReader();
            fileReader.readAsArrayBuffer(inputFile);
            fileReader.onload = (e) => {
                const bufferArray = e.target.result;
                const wb = XLSX.read(bufferArray, { type: "buffer" });
                const wsname = wb.SheetNames[1];
                ... file validations
            };
        }
        this.setState({
            validatingFile: false,
        });
    }



    render() {        
        return (
            <div>
                <h2 className='common-text'>Upload your file below:</h2>
                <input 
                    className='input-block' 
                    type="file" 
                    onChange={this.fileChange} 
                    accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 
                />
                {this.state.validatingFile ? <h6 className='common-text'> Validating File. Please wait!</h6> : ""}
                
        );
    }
}

Advertisement

Answer

Move the final call to set state inside the onload callback:

fileReader.onload = (e) => {
  const bufferArray = e.target.result;
  const wb = XLSX.read(bufferArray, { type: "buffer" });
  const wsname = wb.SheetNames[1];
        
  ... file validations
        
  this.setState({
      validatingFile: false,
  });
};

The onload callback is triggered asynchronously after the file has finished loading. In your current code sample, the call to set state back to false happens before it has processed the data. Since multiple successive state calls are batched, the effect is essentially that no change occurs, even though you set state to true previously.

Advertisement