[React]파일 업로드 컴포넌트

Ryomi·2024년 7월 29일
post-thumbnail

파일 업로드는 웹 애플리케이션에서 자주 필요한 기능 중 하나이다.
나도 현업에서 엄청나게 사용 중임.
첨에 엄청 헤맸다.. 지금은 폼데이터 제왕됨 ;-; 좋은건가?

0. 서론

React에서 react-dropzone 라이브러리를 사용하면 파일 업로드 기능을 구현할 수 있다.
파일 업로드 컴포넌트를 제작하는 방법에 대해 정리한 글이다.

1. 라이브러리 설치

먼저, react-dropzone 라이브러리를 설치한다. 이 라이브러리는 파일 드래그 앤 드롭 기능을 쉽게 구현할 수 있게한다.

npm install react-dropzone

2. 파일 업로드 컴포넌트 작성

react-toast-notifications 이 라이브러리도 유용하니 한 번 사용해봤다.

폼데이터를 props로 넘겨받는 코드이다.

import React, { useState } from 'react';
import { useDropzone, DropzoneRootProps, DropzoneInputProps } from 'react-dropzone';
import { ToastProvider, useToasts } from 'react-toast-notifications'; // Toast 알림 라이브러리 사용

interface FileUploadProps {
  onFormDataChange: (formData: FormData) => void; // 부모 컴포넌트로 formData를 전달할 콜백 함수
}


const FileUpload: React.FC<FileUploadProps> = ({ onFormDataChange }) => {
   const [formData, setFormData] = useState<FormData>(new FormData());

  const handleDrop = (acceptedFiles: File[]) => {
    if (acceptedFiles.length > 0) {
      if (acceptedFiles.length > 1) {
        alert('파일은 하나만 선택 가능합니다!');
      } else {
        const file = acceptedFiles[0];
        formData.append('file', file);
        setFormData(formData);
        onFormDataChange(formData); // 부모 컴포넌트로 formData를 전달합니다.
      }
    }
  };

  const { getRootProps, getInputProps } = useDropzone({
    accept: 'image/*',
    multiple: false,
    onDrop: handleDrop,
  });

  return (
    <div {...getRootProps()} style={dropzoneStyles}>
      <input {...getInputProps()} />
      <p>파일 업로드</p>
    </div>
  );
};

export default FileUpload;

3. 컴포넌트 설명

  • handleDrop 함수: 사용자가 파일을 드래그 앤 드롭하거나 선택했을 때 호출. 하나의 파일만 선택될 수 있도록 구현.
  • useDropzone 훅: react-dropzone에서 제공하는 훅으로, 파일 드래그 앤 드롭 기능을 구현하는 데 사용. accept는 허용할 파일 타입을 설정하며, multiple은 여러 파일을 선택할 수 있는지 여부를 결정합니다.
  • getRootProps와 getInputProps: 드래그 앤 드롭 및 파일 선택을 처리하기 위한 프로퍼티를 제공.

4. 사용 방법

메인 애플리케이션 파일에서 다음과 같이 사용이 가능하다.

import React from 'react';
import ReactDOM from 'react-dom';
import FileUpload from './FileUpload';
import { ToastProvider } from 'react-toast-notifications';

const App: React.FC = () => (
  const [formData, setFormData] = useState<FormData | null>(null);

  const handleFormDataChange = (newFormData: FormData) => {
    setFormData(newFormData); // 자식 컴포넌트에서 전달받은 formData를 상태에 저장
  };

  const handleSubmit = async () => {
    /** axios 사용해서 서버로 보냄 ~ */
  };


  <div>
    <FileUpload onFormDataChange={handleFormDataChange} />
   <button onClick={handleSubmit} disabled={!formData}>
        서버로 전송
      </button>
  </div>
);

ReactDOM.render(<App />, document.getElementById('root'));

이렇게 하면 FileUpload 컴포넌트에서 파일을 선택하고 업로드한 후, formData를 부모 컴포넌트에서 사용할 수 있다. formData는 상태에 저장되며, 이후 handleSubmit 함수를 통해 서버로 전송할 수 있다.

5. 결론

위 예제에서는 파일을 드래그 앤 드롭하거나 클릭하여 선택할 수 있는 파일업로드 버튼 인터페이스를 제공하고, 단일 파일만 업로드하도록 제한했습니다. 필요한 경우 accept 속성을 조정하여 다양한 파일 타입을 지원하도록 변경할 수 있습니다.

profile
making a list, checking it twice 🐥

0개의 댓글