Input을 이용한 이미지 업로드

김민기·2023년 3월 24일
0

게시판 페이지 중 글쓰기 기능을 만들던 도중 파일 업로드 기능이 필요하여 react-quill을 사용하여 이미지 업로드를 하려 하였으나 라이브러리에 대한 이해가 부족하여 직접 파일 업로드 기능을 만들게 되었다.

1. 파일 업로드 함수

 //AppendFile 컴포넌트 
  
const AppendFile = ({ id, onInput }: FileUploadProps) => { 
	const [file, setFile] = useState<any>([]);

    useEffect(() => {
      onInput(file);
    }, [file]);


const pickedHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    let pickedFile = [];

    if (e.target.files) {
      for (let i = 0; i < e.target.files.length; i++) {
        pickedFile.push(e.target.files[i]);
      }
      setFile([...file, ...pickedFile]);
    }
  };
 }

우선, appendfile 컴포넌트를 만들었다.

props로 id와 OnInput 함수를 받아왔다.

OnInput의 함수는 file을 저장할 state로 useEffect로 상태관리를 해주었다.

pickedHandler 함수는 이미지를 저장하는 함수이다.

여러 장의 이미지를 저장하기 위해 pickedFile을 빈배열로 만든 후, 반복문을 써서 length를 순회하게 하였다.

그 후, setFile에 이전값을 복사하고 현재값을 저장하였다.

2. 파일 업로드 삭제 함수

const onDelete = (clickedIndex: number) => {
    const deletedFile = file.filter(
      (_: any, index: number) => index !== clickedIndex
    );

    setFile(deletedFile);
  };

사용자가 이미지를 잘못 올렸거나, 삭제를 하고 싶을 때 클릭하면 삭제하는 함수이다.

Filter를 사용하여 Index를 비교해 삭제하는 기능을 만들었다.

3. 파일 컴포넌트 관리

//File 컴포넌트

const File = ({ item, index, onDelete, key }: any) => {
  return (
    <FileContainer key={key}>
      <FileBox>
        <FileName>{item.name}</FileName>
        <FileDelete
          onClick={() => {
            onDelete(index);
          }}
        >
          x
        </FileDelete>
      </FileBox>
    </FileContainer>
  );
};

사용자가 이미지가 올라갔다는 인지를 하기위해 노출시키는 컴포넌트이다.

컴포넌트를 따로 관리하여 삭제기능을 각각의 컴포넌트에서 관리하였다.

4. formData 전송

  const submit = async () => {
    const formData = new FormData();
    formData.append("title", title);
    formData.append("description", content);
    for (let i = 0; i < file.length; i++) {
      formData.append("image_url", file[i]);
    }
    try {
      if (!title && !content) return alert("제목과 내용을 입력해주세요");
      if (!title) return alert("제목을 입력해주세요");
      if (!content) return alert("내용을 입력해주세요");
      if (file.length === 0) return alert("파일을 첨부해주세요");
      await axios.post("API 주소", formData, {
        headers: { Authorization: localStorage.accessToken },
      });
      alert("완료되었습니다.");
      navigate("/main");
    } catch (error) {
      console.log(error);
    }
  };

이미지를 전송하기 위해서는 formData라는 객체를 이용하여 보내야했다.

여기서 마주쳤던 문제는,

formData.append("image_url",file)

이런 형식으로 보냈었는데, 폼데이터에 file의 value 값이 저장되어지지 않고

key값이 저장되어서 보내졌다.

그래서 반복문으로 file의 value값을 추출하여 폼데이터에 저장하였다.

0개의 댓글