[React] 구매평 모달창 만들기

MOONJUNG·2022년 9월 25일
0

React

목록 보기
9/10
post-thumbnail

레이아웃

1. 모달창 화면 구조

 <>
      <div className="overlay" onClick={clickedModal} />
      <form id="modal" onSubmit={onSubmit}>
      </form>
 </>

1. 모달창 태그 위에 className이 overlay인 어두운 화면을 나타내는 div 박스를 생성하여 준다.

.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: $colorBlack;
  opacity: 0.8;
}
#modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 50%;
  min-width: 500px;
  padding: 30px;
  background-color: $colorWhite;
  text-align: center;
}

2. 어두운 화면과 모달창의 위치를 position:fixed를 준다. 이렇게 하면 구매평 작성 버튼을 눌렀을 때 모달창이 띄어진 느낌이 든다.

useEffect(() => {
    document.body.style = `overflow: hidden`;
    return () => (document.body.style = `overflow: auto`);
  }, []);

2. 스크롤 없애기

3. useEffect를 이용하여 처음 랜더링 후에 화면에 보여졌을 때 body에 overflow: hidden을 주어 scroll을 없앤다.

이미지 미리보기

input태그의 파일 이미지를 useRef에 담기

const imgRef = useRef();
<input type="file"ref={imgRef} />

FileReader 객체에서 제공해주는 readAsDataURL() 메서드로 이미지 URL 가져오기

 const [imageUrl, setImageUrl] = useState(null);

const onChangeImage = () => {
    const reader = new FileReader();
    const file = imgRef.current.files[0];

    reader.readAsDataURL(file);
    reader.onloadend = () => {
      setImageUrl(reader.result);
    };
  };

유저가 이미지를 업로드하면 이미지를 보여주고 아니면 사진첨부하기 텍스트 보여주기

<label
            className="modalLabel"
            htmlFor="reviewImg"
            title="업로드 이미지"
          >
            {imageUrl ? (
              <img className="img" src={imageUrl} alt="uploadImg" />
            ) : (
              <div className="modalBox">
                <i className="fa-solid fa-camera-retro" />
                <h3 className="modalName">사진 첨부하기</h3>
              </div>
            )}
            <input
              id="reviewImg"
              type="file"
              name="image"
              ref={imgRef}
              onChange={onChangeImage}
            />
          </label>

FormData로 서버에 구매평 보내기

1. fetch()로 보낼 때는 method:'POST'

  1. 완료 버튼을 누르면 fetch메서드를 통해 서버에 정보를 보낸다.
const onSubmit = e => {
fetch('url주소', {})
      .then(response => {
        if (response.ok === true) {
          return response.json();
        }
      })
      .then(data => {
        if (data.message === 'Create Review Success') {
          alert('성공');
        } else {
          alert('실패');
        }
      });
}

2. body 안에는 객체 형태 1개만!

  1. fetch 메서드 안에 body값으로 formData 객체를 보내준다.
const onSubmit = e => {
fetch('url주소', {
      method: 'POST',
      headers: {
        authorization: 'TOKEN',
        enctype: 'multipart/form-data',
      },
      body: formData,
    })
      .then(response => {
        if (response.ok === true) {
          return response.json();
        }
      })
      .then(data => {
        if (data.message === 'Create Review Success') {
          alert('성공');
        } else {
          alert('실패');
        }
      });
}

3. 객체 안에 key, value를 추가할 때는 append

  1. formData라는 객체에 이미지와 구매평을 담아 보내준다.
const modal = document.getElementById('modal');
    const formData = new FormData(modal);
    formData.append('productId', productId);

form태그를 사용하면 formData 객체를 생성하였을 때 이미 그 안에 form태그 안에 있는 정보가 객체의 형태로 담겨져 자동으로 서버에 간다.

하지만 productId값을 서버에 추가적으로 보내주어야 하기 때문에
append 메서드를 사용하여 추가한 후에 body에 담아 보내주었다.

마무리하며

파일을 업로드하기 위해서는 input 태그의 타입을 파일로 해야 하고, 자바스크립트에서 FileReader 객체로 이미지 주소를 가져와야 한다는 사실을 새로 알게되었다. 또한 화면에 렌더링 되지는 않고 이미지의 주소(상태)값만 가져올 수 있는 useRef라는 hook을 사용해보았다. 이런 기능을 구현하기 전에 어떤 메서드를 사용해야 할지 고민하는 시간이 참 오래걸린다.

profile
뜨거운 열정으로 꿈을 실현하는 프론트엔드 개발자 장문정

0개의 댓글