개발 계획

제휴 맺기 게시글 작성, 수정, 삭제 기능 구현

개발 기록

제휴 맺기 게시글 작성

게시글을 작성할 때 들어가야 하는 내용은 다음과 같다.

  1. 이미지 (최대 3장)
  2. 글 제목
  3. 작성자 가게
  4. 제휴 기간
  5. 제휴 내용

먼저 이미지 업로드 기능을 처리해보자. 클라이언트에서 서버로 이미지 파일을 전송할 때, File 객체로 전송할 수 있다. 우리는 최대 3장의 이미지를 보낼 수 있도록 하기 위해 input 태그의 multiple 속성을 이용했다. 해당 속성을 true로 설정하면, 브라우저에서 파일을 업로드할 때 여러 개를 한 번에 업로드 할 수 있다.

스크린샷 2022-09-26 오후 4.36.14.png

해당 input 태그에서는 onChange 이벤트를 감지하여 onChangeImage라는 커스텀 함수를 실행하도록 되어있다.

const [imageUrl, setImageUrl] = useState([]);
const [postImages, setPostImages] = useState();

const onChangeImage = () => {
    if (imageUrl.length >= 3) {
      window.alert("3장 이상의 이미지는 등록할 수 없습니다.");
    } else {
      //업로드된 이미지가 3장 미만이라면 imageURL 배열에 추가
      if (imgRef.current.files.length > 0) {
        const imageFiles = [...imgRef.current.files];
        console.log(imageFiles);
        setPostImages(imageFiles);
        imageFiles.map((item) => {
          const reader = new FileReader();
          reader.readAsDataURL(item);
          reader.onloadend = () => {
            setImageUrl((prev) => [...prev, reader.result]);
          };
        });
      }
    }
  };

imageUrl이라는 배열은 미리보기를 위한 배열이고, postImages는 서버로 보내기 위한 이미지 배열이다. 두 변수를 따로 분리한 이유는 미리보기할 때 필요한 이미지의 타입과 서버로 보내기 위한 이미지의 타입이 다르기 때문이다.

onChangeImage 에서는 사용자가 업로드한 파일을 가져와서 PostImages에 그대로 담아주고, 미리보기를 위한 imageUrl에는 FileReader()를 통해 변환을 한 후에 담아준다.

<div className="photoContainer">
              {imageUrl.map((item, index) => {
                return (
                  <div key={index}>
                    <img alt={index} className="uploadedPhoto" src={item}></img>
                    <button id={index} className="deletePhotoBtn" type="button">
                      <IoMdCloseCircle
                        id={index}
                        size={"1.5em"}
                        color={"B8B8B8"}
                        onClick={deletePhoto}
                      ></IoMdCloseCircle>
                    </button>
                  </div>
                );
              })}
            </div>

imageUrl 배열을 map 함수를 통해 하나씩 렌더링 해준다.

스크린샷 2022-09-26 오후 4.44.16.png

이렇게 잘 표시된 미리보기에는 x 버튼이 달려있는데, 이 버튼을 누르면 해당 이미지의 업로드를 취소할 수 있어야 한다.

const deletePhoto = (e) => {
    //버튼 바깥쪽이나 빈 공간을 잘못 클릭한 경우 처리
    if (!e.target.parentNode.parentNode.id) {
      return;
    } else {
      newImageURL = imageUrl.filter((item, index) => {
        return index !== Number(e.target.parentNode.parentNode.id);
      });
      setImageUrl(newImageURL);
    }
  };