이미지 업로드 구현

SongNoin·2021년 10월 1일
0
post-thumbnail

게시판 이미지 업로드 하기

📔 결과물

💻 코드리뷰

  • 일단 이미지를 넣을 수 있는 버튼을 만들어준다
  • map을 이용하여 세개를 만들어 주었다.
  • Uploads01 이란 컴포넌트를 불러왔다.
<Label>사진첨부</Label>
{new Array(3).fill(1).map((el, index) => (
          <Uploads01
            key={`${el}_${index}`}
            index={index}
            onChangeFiles={props.onChangeFiles}
          />
	))}

💻 Uploads01.container

...
export default function Uploads01(props) {
  const fileRef = useRef(null);
  const [fileUrl, setFileUrl] = useState("");
  • 클릭을 하면 파일선택창이 나오게하는 함수
  function onClickUploadImage() {
    fileRef.current?.click();
  }
  • 이미지를 올리기전 파일유무, 파일용량, 파일형식에 대한 검사를 진행해준다.
  async function onChangeImage(event) {
    const file = event.target.files[0];
    if (!file) {
      alert("파일이 없습니다!");
      return;
    }
    if (file.size > 5 * 1024 * 1024) {
      alert("파일 용량이 너무 큽니다. (제한: 5MB");
      return;
    }
    if (!file.type.includes("jpeg") && !file.type.includes("png")) {
      alert("jpeg 또는 png만 업로드 가능합니다.");
      return;
    }
  • fileReader()readAsDataURL() 를 통해 임시 URL으로 변환시켜준다.
  • 이 임시 URL은 본인컴퓨터에서만 쓰이는 URL이고 업로드 시에는 다시 변환시켜줘야한다.
const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.onload = (data) => {
      setFileUrl(data.target?.result);
      props.onChangeFiles(file, props.index);
    };
  }
  return (
...)}

💻 Uploads01.presenter

import {
  UploadImage,
  UploadButton,
  UploadImageHidden,
} from "./Uploads01.styles";
  • 업로드를 위한 버튼(UploadButton)을 만들어주고 위에서 만든 onClick함수를 넣어준다.

  • 파일 URL을 입력하기위한 텍스트상자(UploadImageHidden)을 만들어주고
    위에서 만든 onChange 함수를 넣어준다.

  • 삼항연산자를 이용해서 파일URL이 있으면 이미지 미리보기를,
    없으면 업로드버튼을 보여지게 한다.
export default function Uploads01UI(props) {
  return (
    <>
      {props.fileUrl ? (
        <UploadImage onClick={props.onClickUploadImage} src={props.fileUrl} />
      ) : (
        <UploadButton onClick={props.onClickUploadImage}>
          <div>+</div>
          <div>Upload</div>
        </UploadButton>
      )}
      <UploadImageHidden
        ref={props.fileRef}
        type="file"
        onChange={props.onChangeImage}
      />
    </>
  );
}

업로드를 위한 컴포넌트를 만들어줬다면 게시물 등록페이지에 import 해주고 코드를 작성해준다.

💻 New.container

...
import {
...
  UPLOAD_FILE,
} from "./New.queries";
export default function NewWrite(props) {
  ...
   const [uploadFile] = useMutation(UPLOAD_FILE);
   const [files, setFiles] = useState([null, null, null]);
  • 파일URL이 입력되면 배열에 넣는다.
 function onChangeFiles(file, index) {
    const newFiles = [...files];
    newFiles[index] = file;
    setFiles(newFiles);
  };
  • 등록하기 버튼을 누르면 mapfilter를 사용해서 MutationuploadFile을 이용해서 업로드한다.
  async function onClickSubmit() {
    ...
	try {
      const uploadFiles = files
        .filter((el) => el)
        .map((el) => uploadFile({ variables: { file: el } }));
      const results = await Promise.all(uploadFiles);
      const myImages = results.map((el) => el.data.uploadFile.url);
      ...

업로드를 했다면 게시물조회에서 이미지도 보여져야한다!

💻 Detail.presenter

  • filter로 이미지 URL이 있는것만 이미지를 보여지게한다.
    map으로 사진있는만큼 보여지게한다.
...
{props.data?.fetchBoard.images
            ?.filter((el) => el)
            .map((el) => (
              <Image key={el} src={`https://storage.googleapis.com/${el}`} />
            ))}
...

0개의 댓글