在 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 中全屏拖放文件的主要内容,如果未能解决你的问题,请参考以下文章