React 로 파일 업로드 기능을 구현하기 위해 기존에는 Bootstrap Form Control 에서 type='file'로 구현했었는데,

위와 같이 구현하면 파일을 드래그 앤 드랍 방식으로 업로드를 할 수 없었다.

드래그 앤 드롭 방식의 파일을 업로드를 지원하는 다른 사이트들 처럼 구현해 보고 싶어서 연습을 했다.

 

1. 패키지 설치

React 에서 구현하는 것이 목표이므로 React용 패키지, 그리고 스타일링을 위해 Bootstrap 를 설치했다.

npm install react-dropzone bootstrap

 

2. 기본 구현

파일을 업로드할 화면을 먼저 구현했다.

import { Container, Card } from "react-bootstrap";

const FileUploadFiekd = () => {
    return (
        <Container>
            <Card>
                <p> 이 곳에 파일 업로드 영역이 될 것입니다. </p>
            </Card>
        </Container>
    )
}

export default FileUploadField

 

3. 드래그 앤 드랍 기능 구현

그 다음, 드래그 앤 드랍을 위한 기초 구현으로 useDropzone을 호출한다.

import { Container, Card } from "react-bootstrap";
import { useDropzone } from "react-dropzone";
import { useCallback } from "react";

const Analysis = () => {
    const onDrop = useCallback((file) => {
        console.log(file);
    });

    const {getRootProps, getInputProps, isDragActive} = useDropzone({ onDrop })

    return (
        <Container>
            <Card {...getRootProps()} style={{border: "3px solid black"}}>
                <input {...getInputProps()}/>
                {
                    isDragActive ?
                    <p> 파일이 업로드 되었습니다.</p>:
                    <p> 파일을 업로드 하세요 </p>
                }
            </Card>
        </Container>
    )
}

export default Analysis

위 코드에서

getRootProps은 드래드 앤 드랍 존으로 작동할 요소의 속성과 이벤트 핸들러를 설정하는 역할을 한다.

getInputProps는 input 요소에 적용되며, 사용자가 파일을 선택할 수 있게 하며 input 요소는 보이지 않게 된다.

onDrop 은 파일이 업로드가 되었을 때, 파일 표기 등 후속 작업을 위해 필요한 역할을 한다.

현재 코드에서는 파일이 업로드 되면, 파일 정보를 console 창에 출력하는 역할을 하도록 지정했다.

마지막으로 isDrageActive 는 파일이 업로드 존에 들어와 있는지를 검사하는 역할을 한다.

 

정리하자면 Card 컴포넌트에 getRootProps를 지정하여 해당 영역이 드래그 앤 드랍 존임을 지정하고

하위 요소인 input 에 getInputProps를 설정하여 파일을 받을 수 있도록 지정한다.

isDrageActive는 파일이 업로드 영역에 있는지를 확인하는 역할 (사용자 인지)을 한다.

useDropzone({ onDrop }) 는 파일이 드래그 앤 드랍 혹은 파일이 선택되었을 때 onDrop를 실행할 수 있도록 구현했다.

 

4. 업로드 된 파일 표기 하기

이제 파일이 업로드가 되면, 파일 정보 중 이름을 받아서 화면에 표시하려고 한다.

이를 위해서는 저장할 파일 변수를 만들어 주기 위해 useState 를 활용한다.

import { Container, Card } from "react-bootstrap";
import { useDropzone } from "react-dropzone";
import { useCallback, useState } from "react";

const Analysis = () => {
	const [file, setfile] = useState();

    const onDrop = useCallback((file) => {
        setfile(fileContent);
    });

    const {getRootProps, getInputProps, isDragActive} = useDropzone({ onDrop })

    return (
        <Container>
            <Card {...getRootProps()} style={{border: "3px solid black"}}>
                <input {...getInputProps()}/>
                {
                    isDragActive ?
                    <p> 파일이 업로드 되었습니다.</p>:
                    <p> 파일을 업로드 하세요 </p>
                }
            </Card>
            
            { file ? file[0].name : ''}
            
        </Container>
    )
}

export default Analysis

 

위와 같이 설정한 후, 드래그 앤 드롭 혹은 영역을 선택해서 파일을 업로드 하면 아래와 같이

파일 선택 영역에 파일 이름이 나오게 된다.

 

코드 실행 후 이미지 업로드 결과