在 React 中全屏拖放文件

Posted

技术标签:

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

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

有没有办法在 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;

【讨论】:

以上是关于在 React 中全屏拖放文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PowerShell 中全屏显示

在 WebBrowser 控件中全屏播放 youtube

如何在 Apple TV (TvOS) 中全屏播放视频

在 iOS 上的 Safari 中全屏打开网页

在 WebView 中全屏视频后隐藏菜单栏和停靠

在 Fabric.js 中全屏显示画布