반응형
이제 게시물 작성 & 프로필 사진 변경을 위해 이미지 업로드 기능을 만들 차례가 온 듯하다.
최대한 유지비용을 줄이고 싶어서 초기에 저렴하게, 또는 무료로 이용할 수 있는 서비스를 찾아봤다.

지피티가 정리해줬고 이 중에서 Cloudinary를 사용하기로 했다.
이미지 최적화 처리를 제공하고 초기 10GB까지 무료로 이용할 수 있다는 점에서 선택했다!
🚀 요약
작업 시간: 2시간반
✅ Cloudinary 가입하고 샘플이미지 띄워보기
✅ 프로필 사진 변경 기능 구현 (진행중)
🚀 Cloudinary 가입하고 샘플이미지 띄워보기

클라우디너리 가입하고 Getting Started 페이지 읽어보기
npm i @cloudinary/url-gen @cloudinary/react
SDK 설치
import React from 'react'
import { Cloudinary } from '@cloudinary/url-gen';
import { auto } from '@cloudinary/url-gen/actions/resize';
import { autoGravity } from '@cloudinary/url-gen/qualifiers/gravity';
import { AdvancedImage } from '@cloudinary/react';
const App = () => {
const cld = new Cloudinary({ cloud: { cloudName: 'drhlofiqx' } });
// Use this sample image or upload your own via the Media Explorer
const img = cld
.image('cld-sample-5')
.format('auto') // Optimize delivery by resizing and applying auto-format and auto-quality
.quality('auto')
.resize(auto().gravity(autoGravity()).width(500).height(500)); // Transform the image: auto-crop to square aspect_ratio
return (<AdvancedImage cldImg={img}/>);
};
export default App
리액트 App.js에 추가

화면에 클라우디너리에서 제공하는 이미지 뜨는 것 확인!
🚀 프로필 사진 변경 기능 구현 (진행중)
import { useRef } from "react";
interface ProfileUploaderProps {
imgUrl: string;
onUploadSuccess: (url: string) => void;
}
const ProfileUploader = ({ onUploadSuccess, imgUrl }: ProfileUploaderProps) => {
const inputRef = useRef<HTMLInputElement | null>(null);
const handleClickImage = () => {
inputRef.current?.click();
};
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
const formData = new FormData();
formData.append("file", file);
formData.append("upload_preset", "unsigned_upload");
const res = await fetch(
"https://api.cloudinary.com/v1_1/클라우디너리DB명/image/upload",
{
method: "POST",
body: formData,
}
);
const data = await res.json();
onUploadSuccess(data.secure_url);
};
return (
<div className="w-full flex flex-col items-center justify-center">
<img
className="w-[10rem] h-[10rem] m-1 rounded-full pointer"
src={imgUrl || "/default.png"}
alt="profile"
onClick={handleClickImage}
/>
<input
ref={inputRef}
type="file"
accept="image/*"
className="hidden"
onChange={handleFileChange}
/>
</div>
);
};
export default ProfileUploader;
프로필 이미지를 보여주고, 클릭하면 사진을 업로드하도록 하는 컴포넌트 생성
<ProfileUploader onUploadSuccess={setProfileImg} imgUrl={profileImg} />
상위 컴포넌트에서 호출

처음 회원가입 하면 기본 프로필 사진

프로필 이미지 클릭하면 파일 업로드 창 열림
아직 변경까지 되는지 확인을 못해서 이어 진행할 예정!
반응형
'study > 100 days (100일 챌린지)' 카테고리의 다른 글
[웹개발 100일] Day 47~49 - 게시글 업로드 페이지 UI 구현 (0) | 2025.04.03 |
---|---|
[웹개발 100일] Day 45~46 - 클라이언트의 이미지 업로드 요청 처리해서 Cloudinary 라이브러리에 저장하기 (1) | 2025.03.31 |
여러분 그간 (0) | 2025.03.27 |
[웹개발 100일] Day 34~35 - 프로필 (마이페이지) 수정사항 저장 기능 (2) | 2025.03.20 |
[웹개발 100일] Day 33 - 1주차 주간 정리 (0) | 2025.03.18 |