我希望使用 React Dropzone 在同一组件中创建多个拖放区,我想以不同的方式处理来自每个放置区的文件。这将是具有许多不同放置区的表单的一部分,每个放置区都有不同的参数。首先,我尝试将一些识别信息从特定的拖放区传递到 useDropzone 钩子,以便我最终可以使用不同的函数来处理每个放置区。
如何访问通过 getRootProps 函数传递的 name 属性,以便我可以处理每个丢弃,或者是否有更好的方法来完全完成此操作?在下面的代码中,我能够将事件打印到控制台,但我在事件对象的任何地方都找不到"testtesttest"作为值。我来自getRootProps和getInputProps的props正在覆盖我包含的名称prop,即使我也通过getInputProps函数放置了它。
import React, {useState, useEffect} from 'react';
import {useDropzone} from 'react-dropzone'
import styled from 'styled-components';
const MasterDropzone = styled.div`
height: 150px;
width: 80%;
border: 3px dashed black;
`
function UploadMedia(){
const [masterFile, setMasterFile] = useState({
file: null,
preview: null
});
const {
getRootProps,
getInputProps,
} = useDropzone({
accept: '.jpeg,.png',
noClick: false,
noKeyboard: true,
onDrop: (acceptedFiles,rejected,event) => {
console.log(event)
setMasterFile({
...masterFile,
file: acceptedFiles[0]
})
}
});
useEffect(
() => {
if(!masterFile.file){
setMasterFile({
...masterFile,
preview: undefined
})
return
}
const objectUrl = URL.createObjectURL(masterFile.file)
setMasterFile({
...masterFile,
preview: objectUrl
})
return () => URL.revokeObjectURL(objectUrl)
},
[masterFile.file]
);
return (
<div>
<h1>Upload Media</h1>
{
masterFile.preview
?
<img width='300px' height='300px' src={masterFile.preview} />
:
<MasterDropzone name='testtesttest' {...getRootProps({name: 'testtesttest'})}>
<p>Drag file here or click to upload</p>
<input name='testtesttest'{...getInputProps({name: 'testtesttest'})} />
</MasterDropzone>
}
</div>
)
}
export default UploadMedia
最终通过制作一个 Dropzone 组件并更改每个 dropzone 所需的内容来解决这个问题,这要归功于 Alvaro 的建议。这是我所做的
上传媒体.js
import Dropzone from './Dropzone'
function UploadMedia({ title }){
const [masterFile, setMasterFile] = useState({
content: null,
preview: null
});
const [subtitleFile, setSubtitleFile] = useState({
content: null,
preview: null
})
const [posterImage, setPosterImage] = useState({
content: null,
preview: null
})
const [coverImage, setCoverImage] = useState({
content: null,
preview: null
})
const [featureImage, setFeatureImage] = useState({
content: null,
preview: null
})
const masterText = <p>Master Video File</p>
const subtitleText = <p>Subtitle File</p>
const posterText = <p>Poster Image</p>
const coverText = <p>Cover Photo</p>
const featureText = <p>Feature Photo</p>
async function handleSubmit(evt) {
evt.preventDefault()
console.log('handle files here')
}
return (
<Container>
<h1>Upload media for {title.titleName}</h1>
<Form onSubmit={handleSubmit}>
<Dropzone file={masterFile} setFile={setMasterFile} text={masterText} height='200px' width='70%'/>
<Dropzone file={subtitleFile} setFile={setSubtitleFile} text={subtitleText} height='100px' width='70%'/>
<Dropzone file={posterImage} setFile={setPosterImage} text={posterText} height='200px' width='100px'/>
<Dropzone file={coverImage} setFile={setCoverImage} text={coverText} height='150px' width='350px'/>
<Dropzone file={featureImage} setFile={setFeatureImage} text={featureText} height='200px' width='400px'/>
<button type="submit">Save And Upload</button>
</Form>
</Container>
)
}
export default UploadMedia
空投区.js
function Dropzone({file, setFile, height, width, text}){
const {
getRootProps,
getInputProps,
} = useDropzone({
acceptedFiles: '',
noClick: false,
noKeyboard: true,
onDrop: (acceptedFiles) => {
setFile({
...file,
content: acceptedFiles[0]
})
}
});
useEffect(
() => {
if(!file.content){
setFile({
...file,
preview: undefined
})
return
}
const objectUrl = URL.createObjectURL(file.content)
setFile({
...file,
preview: objectUrl
})
// this line prevents memory leaks, but also removes reference to the image URL
// google chrome will remove this automatically when current session ends
// return () => URL.revokeObjectURL(objectUrl)
},
[file.content]
);
return (
<Container height={height} width={width}>
{
file.preview
?
<img width='40px' height='40px' src={file.preview} />
:
<DropzoneContainer {...getRootProps()}>
{text}
<p>Drag file or click to upload file</p>
<input {...getInputProps()} />
</DropzoneContainer>
}
</Container>
)
}
export default Dropzone