2016-11-07 9 views
0

私はreact-dropzoneを使用している単純なファイルアップロードユーティリティを持っていますが、これに併せてmaterial-ui LinearProgressバーを使用して進捗状況を表示したかったのです。Material-UI LinearProgressバーが動作しません

以下に示すのは、ファイルアップロードユーティリティとLinearProgressバーをレンダリングするコンポーネントです。

私はsuperagentライブラリを使用して、マルチパートフォームデータを使用して実際にバックエンドにバックエンドをアップロードしています。スーパーエージェントの要求は、アップロードの進行状況のためのコールバックまたはイベントハンドラを許可します。私のコードでは、progressイベントハンドラは正常に呼び出され、console.logステートメントによって証明されます。各進行コールで、this.state.completed属性をLinearProgressバーで使用するように更新します。

問題は進行状況バーが前進しないことです。私は間違いなく非常に単純なものを見逃しています。

ご協力いただきまして誠にありがとうございます。

import React, {Component} from 'react'; 
 
import Dropzone from 'react-dropzone'; 
 
import request from 'superagent'; 
 
import LinearProgress from 'material-ui/LinearProgress'; 
 
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 
 

 
export default class MultiFileUpload extends Component { 
 
    constructor(props) { 
 
     super(props); 
 

 
     this.state = { 
 
     completed: 0, 
 
     }; 
 

 
    } 
 
    
 
    onDrop(files) { 
 
     console.log('Received files: ', files); 
 
     this.state.completed = 0; 
 
     var data = new FormData(); 
 
     var req = request.post('/nltools/v1/files/upload'); 
 
     files.forEach((file)=> { 
 
      data.append('files[]', file, file.name); 
 
     }); 
 
     
 
     req.on('progress', (p) => { 
 
     console.log('Last percentage', this.state.completed); 
 
     var percent = Math.floor(p.percent); 
 
     if (percent >= 100) { 
 
      this.setState({completed: 100}); 
 
      console.log('Done 100%'); 
 
     } else { 
 
      this.setState({completed: percent}); 
 
      this.state.completed = percent; 
 
      console.log('Percentage done: ', percent); 
 
     } 
 
     }); 
 

 
     req.send(data); 
 
     req.end(function(err, res){ 
 
      this.state.completed = 0; 
 
      console.log("Successfully uploaded"); 
 
     }); 
 
    } 
 

 
    render() { 
 
     var thisStyle = { 
 
\t \t borderWidth: 4, 
 
\t \t borderColor: "orange", 
 
\t \t borderStyle: "dashed", 
 
\t \t borderRadius: 4, 
 
\t \t margin: 30, 
 
\t \t padding: 30, 
 
\t \t height: 300, 
 
\t \t transition: "all 0.5s" 
 
     }; 
 
     
 
     var progressStyle = { 
 
     margin: 30, 
 
     passing: 30, 
 
     }; 
 

 
     return (
 
     <div> 
 
      <div style={progressStyle}> 
 
      <MuiThemeProvider> 
 
       <LinearProgress color="orange" mode="determinate" value={this.state.completed} /> 
 
      </MuiThemeProvider> 
 
      </div> 
 
      <Dropzone onDrop={this.onDrop} className="dropzone-box" style={thisStyle}> 
 
      <div>Try dropping some files here, or click to select files to upload. {this.state.completed}</div> 
 
      </Dropzone> 
 

 
     </div> 
 
    ); 
 
    } 
 
}

答えて

2

はまず、私はあなたの問題は、このかもしれないと思う:...

onDrop={this.onDrop} 

onDrop={files => this.onDrop(files)} 

かでなければなりません

onDrop={this.onDrop.bind(this)} 

か...

constructor(props) { 
    super(props); 

    this.state = { 
    completed: 0, 
    }; 

    this.onDropHandler = this.onDrop.bind(this); 
} 

// ... then on your component: 
onDrop={this.onDropHandler} 

...それ以外の場合は、すべてのあなたの内部onDropの "この" 参照()正しくありませんので、 "this.state" とは、 "this.setState" だろう失敗します。

また、あなたの状態を決して直接変更するべきではありません。常にsetState()を使用してください。したがって、このようなすべての呼び出しを削除します。

this.state.completed = ???; 

は常に代わりにこれを行う:

this.setState({ completed: ??? }); 

をまた、SETSTATEは非同期です。あなたが何かを持っている必要があれば、状態が更新された後にのみ、あなたは第二引数としてコールバック関数を渡すことができ解雇:

this.setState({ completed: 75 },() => { console.log('state.completed is now 75')); 
// ^^ Immediately after the above call state.completed is probably not 75 yet, 
// because setState() is async 

最後には、あなたのreq.end()の呼び出しに特に注意を払います。そこにはしかありませんは状態を変更しています(やはり悪いです).setState()を呼び出さない(したがって、コンポーネントはreq.end()の後に再レンダリングされません)

+1

これはうまくいきました。私はこれをonDrop自身より進歩に結びつけようとしていました。私はthis.state.completed = xyzのように状態を変更しない方法についてこの質問を投稿した後に学んだ – user320599

0

完全な例:

import React, { Component } from "react"; 
import ReactDOM from "react-dom"; 
import Dropzone from "react-dropzone"; 
import request from "superagent"; 
import { Line } from 'rc-progress'; 

class App extends Component { 
    state = { 
     completed: 0 
    } 

    onDrop = files => { 
    this.setState({ completed: 0 }); 
    var data = new FormData(); 
    files.forEach(file => { 
     data.append("files[]", file, file.name); 
    }); 

    var req = request.post("http://localhost:3001"); 
    req.on('progress', event => { 
     var percent = Math.floor(event.percent); 
     if (percent >= 100) { 
     this.setState({ completed: 100 }); 
     } else { 
     this.setState({ completed: percent }); 
     } 
    }); 

    const that = this; 
    req.send(data); 
    req.end((err, res) => { 
     console.log("Successfully uploaded"); 
    }); 
    }; 

    render() { 
    const divStyle = { 
     border: '1px solid black' 
    }; 
    return (
     <div style={divStyle}> 
     <Dropzone onDrop={this.onDrop} className="dropzone-box"> 
      <div>Try dropping some files here, or click to select files to upload. {this.state.completed}</div> 
      <Line percent={this.state.completed} strokeWidth="0.5" strokeColor="#2db7f5" strokeLinecap="square" /> 
     </Dropzone> 
     </div> 
    ); 
    } 
} 

ReactDOM.render(<App />, document.getElementById("root")); 
関連する問題