【问题标题】:Material-UI LinearProgress bar not workingMaterial-UI LinearProgress 栏不起作用
【发布时间】:2016-11-07 23:15:08
【问题描述】:

我有一个简单的文件上传实用程序,为此我使用react-dropzone,并结合使用material-ui LinearProgress 栏来显示进度。

下面显示的是我创建的组件,它与 LinearProgress 栏一起呈现文件上传实用程序。

我正在使用superagent 库使用多部分表单数据将后端实际上传到后端。超级代理的请求允许回调或事件处理程序用于上传进度。在我的代码中,进度事件处理程序被成功调用并由 console.log 语句证明。在每次进度调用中,我都会更新 LinearProgress 栏使用的 this.state.completed 属性。

问题是进度条不前进。我肯定错过了一些非常简单的东西。

非常感谢任何帮助,并提前感谢您。

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 = {
		borderWidth: 4,
		borderColor: "orange",
		borderStyle: "dashed",
		borderRadius: 4,
		margin: 30,
		padding: 30,
		height: 300,
		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>
      );
    }
}

【问题讨论】:

    标签: reactjs react-jsx material-ui


    【解决方案1】:

    首先,我认为你的问题可能是这样的:

    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”引用都将不正确,因此“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( ))

    【讨论】:

    • 那行得通。我一直试图将此绑定到进度而不是 onDrop 本身。我在发布这个关于如何不改变状态的问题后了解到 this.state.completed = xyz
    【解决方案2】:

    完整示例:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      • 2015-09-26
      • 1970-01-01
      • 2020-07-09
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多