React Hooks로 하나의 제출 버튼으로 여러 파일 입력

21634 단어 reactinputfileshooks
최근에 프로젝트를 진행 중이었고 여러 파일을 입력해야 했습니다. 문제는 모든 입력이 제 경우에는 pdf , jpeg 전용인 특정 유형의 파일 하나만 가져와야 한다는 것입니다. 파일을 업로드한 후 사용자는 하나의 제출 버튼을 사용하여 업로드된 모든 파일을 함께 제출해야 합니다. 제 경우에는 사용자가 모든 파일을 한 번에 업로드할 필요가 없습니다.

가장 먼저 떠오른 것은 FormData ; 그러나 각 개체에 file_Id와 파일 자체가 있어야 하는 개체 배열을 제출해야 했으며 이 예에서는 이것을 upload_file이라고 합시다. FormData로 저는 그렇게 할 수 없어서 제 방식대로 만들었습니다.

이 예제에서는 Reactjs와 hooks에 익숙하다고 가정합니다.

다음은 목표를 달성하기 위해 수행한 단계입니다.

1. 3개의 입력 파일로 React 구성 요소를 생성합니다. 각 입력 파일은 고유 ID가 있는 pdf, jpeg만 허용합니다. 또한 1개의 제출 버튼이 필요합니다.

import React from 'react';

const MultipleFileInput = () => {
  return (
    <form className="upload--container">
      <div className="upload--button">
        <input id={1} accept=".jpeg, .pdf" type="file" />
      </div>
      <div className="upload--button">
        <input id={2} accept=".jpeg, .pdf" type="file" />
      </div>
      <div className="upload--button">
        <input id={3} accept=".jpeg, .pdf" type="file" />
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};

export default MultipleFileInput;


2. 객체 배열을 보유할 상태를 생성합니다.

  // state that will hold the Array of objects
  // initialized with empty array
  const [files, setFiles] = useState([]);


3. 각 입력 파일에 대해 onChageHandler를 추가합니다. 이 파일을 읽으려면 내가 사용한FileReader 자세히 알아보기FileReader Web API

// onChange function that reads files on uploading them
// files read are encoded as Base64
  function onFileUpload(event) {
    event.preventDefault();
    // Get the file Id
    let id = event.target.id;
    // Create an instance of FileReader API
    let file_reader = new FileReader();
    // Get the actual file itself
    let file = event.target.files[0];
    file_reader.onload = () => {
    // After uploading the file
    // appending the file to our state array
    // set the object keys and values accordingly
      setFiles([...files, { file_id: id, uploaded_file: file_reader.result }]);
    };
   // reading the actual uploaded file
    file_reader.readAsDataURL(file);
  }


4. 이제 제출 버튼을 구현해 보겠습니다. 이 예에서는 결과를 콘솔에 기록할 것입니다. 그러나 이 파일을 서버로 보내야 했습니다.

  // handle submit button for form
  function handleSubmit(e) {
    e.preventDefault();
    console.log(files)
  }


5. 마지막으로 논리에 몇 가지 제한 사항을 추가해 보겠습니다. 예를 들어 업로드된 파일이 없으면 제출 버튼을 비활성화합니다.

// button state whether it's disabled or enabled
  const [enabled, setEnabled] = useState(false);
  // using useEffect we can detect if user uploaded any file, 
  // so enable submit button
  useEffect(() => {
    if (files.length === 0) {
      setEnabled(false);
    } else {
      setEnabled(true);
    }
  }, [files]);
// render submit button based on its state. 
{enabled ? (
        <button type="submit">Submit</button>
      ) : (
        <button disabled type="submit">
          Submit
        </button>
 )}


이것은 결국 전체 코드가 될 것입니다.

코드산독스Link


import React, { useState, useEffect } from 'react';

const MultipleFileInput = () => {
  // state that will hold the Array of objects
  // initialized with empty array
  const [files, setFiles] = useState([]);
  // onChange function that reads files on uploading them
  // files read are encoded as Base64
  function onFileUpload(event) {
    event.preventDefault();
    // Get the file Id
    let id = event.target.id;
    // Create an instance of FileReader API
    let file_reader = new FileReader();
    // Get the actual file itself
    let file = event.target.files[0];
    file_reader.onload = () => {
      // After uploading the file
      // appending the file to our state array
      // set the object keys and values accordingly
      setFiles([...files, { file_id: id, uploaded_file: file_reader.result }]);
    };
    // reading the actual uploaded file
    file_reader.readAsDataURL(file);
  }
  // handle submit button for form
  function handleSubmit(e) {
    e.preventDefault();
    console.log(files);
  }
  // button state whether it's disabled or enabled
  const [enabled, setEnabled] = useState(false);
  // using useEffect we can detect if user uploaded any file,
  // so enable submit button
  useEffect(() => {
    if (files.length === 0) {
      setEnabled(false);
    } else {
      setEnabled(true);
    }
  }, [files]);

  return (
    <form onSubmit={handleSubmit} className="upload--container">
      <h1> Multiple File Inputs with Signle Submit Button </h1>
      <div className="upload--button">
        <input
          onChange={onFileUpload}
          id={1}
          accept=".jpeg, .pdf"
          type="file"
        />
      </div>
      <div className="upload--button">
        <input
          onChange={onFileUpload}
          id={2}
          accept=".jpeg, .pdf"
          type="file"
        />
      </div>
      <div className="upload--button">
        <input
          onChange={onFileUpload}
          id={3}
          accept=".jpeg, .pdf"
          type="file"
        />
      </div>
      {enabled ? (
        <button type="submit">Submit</button>
      ) : (
        <button disabled type="submit">
          Submit
        </button>
      )}
    </form>
  );
};

export default MultipleFileInput;


마지막 말,



누군가 다른 접근 방식을 공유하거나 현재 구현에 대한 수정 사항을 공유하면 기쁠 것입니다. 그러니 주저하지 마시고 여러분의 생각을 공유해 주십시오.

좋은 웹페이지 즐겨찾기