web-dev-qa-db-ja.com

ReactJSbase64ファイルのアップロード

私はこの関数をReactコンポーネントに持っています

handleChangeImage: function (evt) {
    console.log("Uploading");
    var self = this;
    var reader = new FileReader();
    var file = evt.target.files[0];

    reader.onload = function(upload) {
        self.setState({
            image: upload.target.result
        });
    };
    reader.readAsDataURL(file);
    console.log(this.state.image);
    console.log("Uploaded");
},

ここで呼ばれます

<input ref="file" type="file" name="file" 
                              className="upload-file" 
                              id="file"
                              onChange={this.handleChangeImage}
                              encType="multipart/form-data" 
                              required/>

AJAXを介してFlaskを実行しているサーバーに送信するbase64文字列を取得しようとしています。問題は、ファイルを選択するたびに、nullとしてログに記録されることです。コンソール

面白いことに、もう一度ファイルを選択しようとすると、文字列全体がログに記録されます。シンプルなものが欠けているに違いない...

7
edwardffs

印刷時に状態が変更されていないため、コンソールではnullとしてログに記録されます。 2回目にファイルを選択すると、コンソールにログインした文字列は、実際には前に選択したファイルに属します。状態は、選択した2番目のファイルにまだ変更されていません。

Reactのドキュメント を参照:

setState()はthis.stateをすぐに変更しませんが、保留中の状態遷移を作成します。このメソッドを呼び出した後にthis.stateにアクセスすると、既存の値が返される可能性があります。 setStateへの呼び出しの同期操作の保証はなく、パフォーマンスを向上させるために呼び出しをバッチ処理することができます。

正しい状態を出力したい場合は、コールバック関数に記録できます。

self.setState({
    image: upload.target.result
}, function() {
    console.log(self.state.image);
});

これは、1秒の遅延後に状態を変更する必要があるためも機能します。

reader.onload = function(upload) {
    self.setState({
        image: upload.target.result
    });
};
reader.readAsDataURL(file);    
setTimeout(function() {
  console.log(self.state.image);
}, 1000);
8
Siu