立即反应setstate并重新提交

时间:2018-07-03 09:55:48

标签: reactjs

我是新来的反应者,只是尝试通过输入标签上传文件,因为文件可能很大,所以在上传时,我想向用户显示系统当前正在处理UI中的某些文本,如“正在上传...”。 。'。为此,我正在做:

import PropTypes from 'prop-types';
import React from 'react';
import createReactClass from 'create-react-class';
import i18n from 'ar-i18n';
import _ from 'lodash';

const DragAndDropContainer = createReactClass({
propTypes: {
    onDropFile: PropTypes.func.isRequired,
},

getInitialState () {
    return { currentFile: null, uploadState: false };
},

render () {
    const dragAndDropId = _.uniqueId('drag-and-drop-file-');
    return (
        <div className='drag-and-drop-container'>
            {

                this.state.currentFile && (
                    <p className='drag-and-drop-current-file'>
                        <strong>{ this.state.currentFile.name }</strong>
                    </p>
                )

            }
            {

                !this.state.currentFile && this.state.uploadState && (
                    <p className='drag-and-drop-current-file'>
                        <strong>{i18n.gettext('Uploading......')}</strong>
                    </p>
                )

            }

            <div
                className='drag-and-drop-area'
                onDragEnter={e => e.preventDefault()}

                onDrop={this.onDrop}
                onDragOver={e => e.preventDefault()}
            >
                <img src={assetUrl('upload.png')} />
                <input
                    id={dragAndDropId}
                    className='drag-and-drop-file'
                    name='files[]'
                    type='file'
                    onChange={this.onFileSelected}
                />
                <p>
                    <label className='drag-and-drop-label' htmlFor={dragAndDropId}>
                        <strong>{i18n.gettext('Choose a file or drop it here')}</strong>
                    </label>
                </p>
            </div>
        </div>
    );
},

onDrop (e) {
    this.onFileSelected(e);
    e.preventDefault();
},

onFileSelected (e) {
    this.setState({ uploadState: true }, function () {console.log('updated uplodastate---', this.state.uploadState)});
    const file = e.dataTransfer ? e.dataTransfer.files[0] : e.currentTarget.files[0];
    this.setState({ currentFile: file });
    this.props.onDropFile(file);
    // prevents control from "caching" files with same name in consecutive uploads
    e.currentTarget.value = '';
},


});

export default DragAndDropContainer;

由于异步调用setState,因此条件!this.state.currentFile && this.state.uploadState永远不会为真。

如何在this.state.uploadState之前设置const file = e.dataTransfer ? e.dataTransfer.files[0] : e.currentTarget.files[0];允许它调用渲染。

2 个答案:

答案 0 :(得分:0)

一个人可以将currentFile状态更新放入回调中以满足条件。

this.setState({
    uploadState: true
}, ()=> {
    console.log('updated uplodastate---', this.state.uploadState);

    const file = e.dataTransfer ? e.dataTransfer.files[0] : e.currentTarget.files[0];
    this.setState({
        currentFile: file
    });

});

答案 1 :(得分:0)

您需要在setState之后设置const file = e.dataTransfer ? e.dataTransfer.files[0] : e.currentTarget.files[0],一旦状态更新,它将自动重新呈现组件。

这称为回调函数。

onFileSelected (e) {
    this.setState({ uploadState: true }, function () {
      const file = e.dataTransfer ? e.dataTransfer.files[0] : e.currentTarget.files[0];
      this.setState({ currentFile: file });
    });
    this.props.onDropFile(file);
    e.currentTarget.value = '';
}