Доступ к свойству name в компоненте React Dropzone - PullRequest
3 голосов
/ 05 февраля 2020

Я хочу создать несколько дропзон в одном компоненте с помощью React Dropzone и хочу по-разному обрабатывать файл из каждой дропзоны. Это будет частью формы с множеством разных дропзон, каждая из которых имеет разные параметры. Для начала я пытаюсь передать некоторую идентифицирующую информацию из определенной дропзоны в хук useDropzone, чтобы в конечном итоге я мог использовать разные функции для обработки каждой дропзоны.

Как получить доступ к свойству name, переданному через функцию getRootProps так что я могу справиться с каждой каплей, или есть лучший способ сделать это полностью? В приведенном ниже коде мне удалось вывести событие на консоль, но я не могу найти «testtesttest» в качестве значения нигде в объекте события. Если реквизиты из getRootProps и getInputProps переопределяют добавленную мной опору имени, хотя я также поставил ее через функцию 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

1 Ответ

1 голос
/ 14 февраля 2020

Закончилось решение этой проблемы путем создания компонента Dropzone и изменения того, что мне было нужно для каждой dropzone с помощью реквизита, благодаря предложению Альваро. Вот что я сделал

UploadMedia. 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

Dropzone. 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
...