메인 프로젝트와 마지막 잡서칭 기간을 지나며 6개월의 여정이 막을 내렸다. 부트캠프의 꽃인 프로젝트 기간을 거치며 치열하게 공부하고 팀원들과의 크고 작은 갈등을 거치며 하드 스킬 뿐만 아니라 소프트 스킬도 기를 수 있어 그 어느 때보다 의미있는 시간을 보내었던 것 같다. 수용적인 팀원들을 만나 큰 사건사고 없이 프로젝트 배포까지 끝마칠 수 있었던 점에 감사하며 다시 마음을 다잡고 공부해야겠다🙏
부트캠프에서 프리 프로젝트와 메인 프로젝트를 약 두 달 간 진행하며 많은 배움을 얻은 시간이었지만 블로깅에는 다소 소홀했던 모습을 반성하며 프로젝트를 진행하며 배웠던 것들에 대해 하나하나씩 글로 작성해보자는 다짐을 하게 되었다.
첫 번째 블로깅 주제로는 '이미지를 등록하는 두 가지 방법'을 선택했다. 서버에서 상품등록(관리자페이지) 시 이미지를 등록하는 방법과 프로필 이미지(마이페이지)를 등록하는 방법을 다른 방식으로 구현해놓았기 때문에 프론트엔드에서도 약간 다른 방식으로 구현해주어야 했다. 이미지를 등록할 때 type이 file인 input 태그를 이용하였는데 이 파일을 url로 post하는 방식과 파일을 aws s3에 업로드하는 두 가지 방식이다. 물론 이미지를 post하는 방식에는 많은 방식이 있지만 메인 프로젝트에서 서로 다른 방식을 접해볼 수 있었다는 점에서 재미있었던 기억이 있어 이용한 두 가지 방식만 블로깅해보려 한다.
참고: 서버와 통신 시 HTTP 비동기 통신 라이브러리인 axios를 사용
// FileReader 객체 생성
const reader = new FileReader();
// file의 change 이벤트 발생 시 실행되는 함수
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
// load 이벤트의 핸들러로 읽기 동작이 성공적으로 완료되었을 때마다 발생
reader.onload = function (e) {
if (typeof e.target?.result === "string") {
setImage(e.target.result);
}
};
// readAsDataURL 메서드: 컨텐츠를 특정 Blob 이나 File에서 읽어 오는 역할
// 읽기 동작이 완료되었을 경우, base64 방식으로 인코딩 된 스트링 데이터가 result 속성에 담김
reader.readAsDataURL(e.target.files[0]);
}
};
// post 요청 시
axios
.post(
"http://서버 주소/admin",
{
productName: productName,
price: Number(price),
imgName: "img",
// setImage라는 상태관리함수를 통해 변경된 image라는 상태를 post
// image에는 파일의 url이 담겨있음
imgUrl: image,
productCategory: selectedStore,
},
{
headers: {
Authorization: localStorage.getItem("token"),
},
}
)
// file의 change 이벤트 발생 시 실행되는 함수
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
// 새로운 FormData 객체 생성
// formdata: 폼(이미지 등)을 비동기로 전송하고 싶은 경우 사용하는 객체
const formData = new FormData();
// FormData.append 메서드: FormData 객체의 기존 키에 새 값을 추가하거나 키가 없는 경우 키를 추가하는 메서드
// 형식: FormData.append(키, 값)
formData.append("multipartFileList", e.target.files[0]);
}
};
// post 요청 시
axios
.post("http://서버 주소/upload", formData, {
headers: {
Authorization: localStorage.getItem("token"),
// 파일 전송 시 헤더에 토큰 뿐만 아니라 content-type을 multipart/form-data로 지정해주어야 함
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
setImage(res.data[0]);
})
.catch((err) => console.log(err));
참고
FileReader
FileReader.readAsDataURL()
FormData
FormData.append()