【问题标题】:Full screen drag and drop files in React在 React 中全屏拖放文件
【发布时间】:2019-03-18 10:14:22
【问题描述】:

在 react-dropzone 的this official example 中,通过将整个应用包裹在<Dropzone /> 组件中来实现全屏拖放区。我正在创建一个多路由应用程序,并且觉得将所有内容包装在 <Dropzone /> 组件中并不是一个非常干净的解决方案。

有没有办法在 React 中创建一个全屏/页面拖放区而不将 <Dropzone /> 组件放在根级别?

【问题讨论】:

    标签: reactjs drag-and-drop react-dropzone


    【解决方案1】:

    创建到Dropzone 表单的路由,并利用CSS 调整field 的高度和大小。

    工作示例:https://codesandbox.io/s/l77212orwz(此示例使用 Redux 表单,但您不必这样做)

    容器/UploadForm.js

    import React, { Component } from "react";
    import { reduxForm } from "redux-form";
    import ShowForm from "../components/showForm";
    
    class UploadImageForm extends Component {
      state = { imageFile: [] };
    
      handleFormSubmit = formProps => {
        const fd = new FormData();
        fd.append("imageFile", formProps.imageToUpload[0]);
        // append any additional Redux form fields
        // create an AJAX request here with the created formData
      };
    
      handleOnDrop = newImageFile => this.setState({ imageFile: newImageFile });
    
      resetForm = () => {
        this.setState({ imageFile: [] });
        this.props.reset();
      };
    
      render = () => (
        <div style={{ padding: 10 }}>
          <ShowForm
            handleOnDrop={this.handleOnDrop}
            resetForm={this.resetForm}
            handleFormSubmit={this.handleFormSubmit}
            {...this.props}
            {...this.state}
          />
        </div>
      );
    }
    
    export default reduxForm({ form: "UploadImageForm" })(UploadImageForm);
    

    components/showForm.js

    import isEmpty from "lodash/isEmpty";
    import React from "react";
    import { Form, Field } from "redux-form";
    import DropZoneField from "./dropzoneField";
    
    const imageIsRequired = value => (isEmpty(value) ? "Required" : undefined);
    
    export default ({
      handleFormSubmit,
      handleOnDrop,
      handleSubmit,
      imageFile,
      pristine,
      resetForm,
      submitting
    }) => (
      <Form onSubmit={handleSubmit(handleFormSubmit)}>
        <Field
          name="imageToUpload"
          component={DropZoneField}
          type="file"
          imagefile={imageFile}
          handleOnDrop={handleOnDrop}
          validate={[imageIsRequired]}
        />
        <button
          type="submit"
          className="uk-button uk-button-primary uk-button-large"
          disabled={submitting}
        >
          Submit
        </button>
        <button
          type="button"
          className="uk-button uk-button-default uk-button-large"
          disabled={pristine || submitting}
          onClick={resetForm}
          style={{ float: "right" }}
        >
          Clear
        </button>
      </Form>
    );
    

    components/dropzoneField.js

    import React, { Fragment } from "react";
    import DropZone from "react-dropzone";
    import { MdCloudUpload } from "react-icons/md";
    import RenderImagePreview from "./renderImagePreview";
    
    export default ({
      handleOnDrop,
      input,
      imagefile,
      meta: { error, touched }
    }) => (
      <div>
        <DropZone
          accept="image/jpeg, image/png, image/gif, image/bmp"
          className="upload-container"
          onDrop={handleOnDrop}
          onChange={file => input.onChange(file)}
        >
          <div className="dropzone-container">
            <div className="dropzone-area">
              {imagefile && imagefile.length > 0 ? (
                <RenderImagePreview imagefile={imagefile} />
              ) : (
                <Fragment>
                  <MdCloudUpload style={{ fontSize: 100, marginBottom: 0 }} />
                  <p>Click or drag image file to this area to upload.</p>
                </Fragment>
              )}
            </div>
          </div>
        </DropZone>
        {touched && error && <div style={{ color: "red" }}>{error}</div>}
      </div>
    );
    

    components/renderImagePreview.js

    import map from "lodash/map";
    import React from "react";
    
    export default ({ imagefile }) =>
      map(imagefile, ({ name, preview, size }) => (
        <ul key={name}>
          <li>
            <img src={preview} alt={name} />
          </li>
          <li style={{ textAlign: "center" }} key="imageDetails">
            {name} - {size} bytes
          </li>
        </ul>
      ));
    

    styles.css

    .dropzone-container {
      text-align: center;
      background-color: #efebeb;
      height: 100%;
      width: 100%;
    }
    
    .dropzone-area {
      margin: 0;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    
    .upload-container {
      height: 100vh;
      width: 100%;
      margin-bottom: 10px;
    }
    
    ul {
      list-style-type: none;
    }
    
    p {
      margin-top: 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 2018-01-08
      • 2021-12-24
      • 1970-01-01
      • 1970-01-01
      • 2021-07-03
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      相关资源
      最近更新 更多