이미지 Drag and Drop 구현해보기

버건디·2023년 8월 17일
0

Next.js

목록 보기
45/52
post-thumbnail

프로젝트 진행중에, 이미지를 업로드할때 드래그 앤 드랍을 이용해서 이미지 업로드 하는 기능을 구현하고 싶었다.

드래그 앤 드랍을 구현하려면 drag 관련 이벤트 속성을 알아두는 것이 필요하다.

  1. onDragEnter
  • 드래그하는 항목이 특정 요소의 경계를 처음 들어갈 때 한 번만 발생하는 이벤트
  1. onDragOver
  • 드래그 중인 항목이 해당 요소 위에 머물러 있을 때 지속적으로 발생하는 이벤트
  1. onDragLeave
  • 드래그 중인 항목이 해당 요소의 범위를 벗어날때 발생하는 이벤트
  1. onDrop
  • 드래그 중인 항목을 해당 요소의 범위에 놓을때 발생하는 이벤트

- 상태 변화 코드 부분


export default function Component() {
  const [dragging, setDragging] = useState(false);
  const [file, setFile] = useState<File | null>(null);
    const [previewUrl, setPreviewUrl] = useState<string | null | undefined>();
  
  
  useEffect(() => {
    if (!file) {
      return;
    }
    const fileReader = new FileReader();
    fileReader.onload = () => {
      if (typeof fileReader.result === "string") {
        setPreviewUrl(fileReader.result);
      }
    };
    fileReader.readAsDataURL(file);
  }, [file]);

  const onDragEnterHandler = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    setDragging(true);
  };
  const onDragLeaveHandler = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    setDragging(false);
  };
  const onDragOverHandler = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.dataTransfer.files) {
      setDragging(true);
    }
  };
  const onDropHandler = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    setDragging(false);

    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
      setFile(e.dataTransfer.files[0]);
      e.dataTransfer.clearData();
    }
  };
  
            <div
              className={
                dragging
                  ? `${classes.image_input_container} ${classes.dragging}`
                  : classes.image_input_container
              }
              onDragEnter={onDragEnterHandler}
              onDragLeave={onDragLeaveHandler}
              onDragOver={onDragOverHandler}
              onDrop={onDropHandler}
            >
              {!previewUrl && (
                <>
                  <input
                    required
                    type={"file"}
                    accept={".svg"}
                    className={classes.image_input}
                    multiple={false}
                    aria-hidden
                    id="image_upload"
                  />
                  <div className={classes.icon_container}>
                    <BsFillImageFill />
                  </div>
                  <label
                    htmlFor="image_upload"
                    className={classes.image_input_label}
                  >
                    이미지 가져오기
                  </label>
                </>
              )}

              {previewUrl && (
                <Image
                  src={previewUrl}
                  width={300}
                  height={300}
                  alt="image"
                  className={classes.preview_image}
                />
              )}
            </div>

input 부분을 숨겨주고, 이미지가 업로드될때, previewUrl에 파일 경로를 담아줌으로써

이미지가 나타나도록 했다.

profile
https://brgndy.me/ 로 옮기는 중입니다 :)

0개의 댓글