본문 바로가기

NEW(스크립트용)

react input type files 의 이미지 mapping 및 삭제 (dataTransfer.items.add, Array.slice(index,1) 사용)

import React, { useState } from "react";
import "../../App.css";
const FilesSize = () => {
  //files:실제파일, selected: 파일가상주소
  const [files, setFiles] = useState([]);
  const [selected, setSelected] = useState([]);
  const imageHandleChange = (e) => {
    //filesize
    const activeFiles = Array.from(e.target.files);
    let toastShow = false;
    activeFiles.forEach((el) => {
      console.log(el.size);
      if (el.size / 1000000 > 15) {
        toastShow = true;
      }
    });
    if (toastShow) {
      alert("this file is over 15mb");
    }
    //virtualurl : 미리보기 가상의 주소 만들기
    const virtualURLArray = activeFiles.map((file) =>
      URL.createObjectURL(file)
    );
    //dataTransfer로 이전파일 + activeFiles를 묶은 후 각각 file로 분리
    const dataTransfer = new DataTransfer();
    files
      .concat(activeFiles)
      .slice(0, 5)
      .forEach((file) => {
        dataTransfer.items.add(file);
      });
    document.getElementById("file").files = dataTransfer.files;

    setFiles([...Array.from(dataTransfer.files)]);
    setSelected(selected.concat(virtualURLArray).slice(0, 5));
  };
  const deleteImage = (el, index) => {
    selected.splice(index < selected.length ? index : index - 1, 1);
    setSelected([...selected]);
  };

  return (
    <div className="flex">
      <input
        type="file"
        accept=".jpg, .png, .jpeg"
        multiple
        id="file"
        hidden
        onChange={imageHandleChange}
      />
      <div className="label-holder">
        <label htmlFor="file" className="label">
          <div
            style={{
              width: "88px",
              height: "88px",
              backgroundColor: "red",
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              position: "relative",
              cursor: "pointer"
            }}
          >
            click
          </div>
        </label>
      </div>
      <div className="result">
        {selected.map((el, index) => (
          <div className="relative">
            <img
              src={el}
              alt={index}
              style={{
                width: "80px"
              }}
            />
            <span
              className="cursorpointer"
              style={{
                position: "absolute",
                top: "10px",
                right: "10px"
              }}
              onClick={deleteImage}
            >
              X
            </span>
          </div>
        ))}
      </div>
    </div>
  );
};

export default FilesSize;