<>
<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`);
}, []);
3. useEffect를 이용하여 처음 랜더링 후에 화면에 보여졌을 때 body에 overflow: hidden
을 주어 scroll을 없앤다.
const imgRef = useRef();
<input type="file"ref={imgRef} />
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>
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('실패');
}
});
}
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('실패');
}
});
}
const modal = document.getElementById('modal');
const formData = new FormData(modal);
formData.append('productId', productId);
form태그를 사용하면 formData 객체를 생성하였을 때 이미 그 안에 form태그 안에 있는 정보가 객체의 형태로 담겨져 자동으로 서버에 간다.
하지만 productId값을 서버에 추가적으로 보내주어야 하기 때문에
append 메서드를 사용하여 추가한 후에 body에 담아 보내주었다.
파일을 업로드하기 위해서는 input 태그의 타입을 파일로 해야 하고, 자바스크립트에서 FileReader 객체로 이미지 주소를 가져와야 한다는 사실을 새로 알게되었다. 또한 화면에 렌더링 되지는 않고 이미지의 주소(상태)값만 가져올 수 있는 useRef라는 hook을 사용해보았다. 이런 기능을 구현하기 전에 어떤 메서드를 사용해야 할지 고민하는 시간이 참 오래걸린다.