
// 상태 관리
const [profileImage, setProfileImage] = useState<File | null>(null);
const [previewUrl, setPreviewUrl] = useState<string>(profile_url || "");
// 클릭
const handleImageClick = () => {
document.getElementById("profileImage")?.click();
};
// 파일 url 변환 후 미리보기 상태에 저장
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const fileObj = e.target.files?.[0];
if (fileObj) {
setProfileImage(fileObj);
const objectUrl = URL.createObjectURL(fileObj);
setPreviewUrl(objectUrl);
}
};
// 미리보기 이미지
<div onClick={handleImageClick} className="relative w-24 h-24 mb-4 cursor-pointer">
<Image
src={previewUrl}
alt="Profile Image"
layout="intrinsic"
width={96}
height={96}
objectFit="cover"
className="rounded-full border-2 border-gray-300"/>
<input type="file" id="profileImage" className="hidden" accept="image/*" onChange={handleImageChange} />
</div>
// 상태 관리
const [profileImage, setProfileImage] = useState<File | null>(null);
const [profileImageUrl, setProfileImageUrl] = useState<string>(profile_url || "");
// supbase 스토리지 저장
// profiles 버킷에 public이라는 폴더 안에
// `public/${crypto.randomUUID()}.png` 이름으로 profileImage 를 저장
if (profileImage) {
const { data: avatarData, error: uploadError } = await supabase.storage
.from("profiles")
.upload(`public/${crypto.randomUUID()}.png`, profileImage);
if (uploadError) {
console.error("Error uploading image:", uploadError);
return;
}
// url 가져오기
const { data: publicUrlData } = supabase.storage.from("profiles").getPublicUrl(avatarData.path);
setProfileImageUrl(publicUrlData.publicUrl);
fetch vs axios)마이페이지 기능 구현이 끝났고 refatoring 과정에서 고민이 생겼다. (비교는 Learn부분에서)
const { data: likes = [], error, isPending} = useQuery<Like[]>({
queryKey: ['likes', id, contentType, carouselName],
queryFn: async () => {
const url = contentType
? `/api/filterlikes?id=${id}&contentType=${contentType}`
: `/api/likes?id=${id}`;
const response = await fetch(url, { cache: "force-cache" });
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
},
enabled: !!id,
});
if (isPending) {
return <LoadingPage />;
}
if (error) {
return <div>Error fetching likes: {error.message}</div>;
}
const {
data: likes = [],
error,
isPending,
} = useQuery<Like[]>({
queryKey: ["likes", id, contentType, carouselName],
queryFn: async () => {
const url = contentType ? `/api/filterlikes?id=${id}&contentType=${contentType}` : `/api/likes?id=${id}`;
const cacheKey = `likes-${id}-${contentType || ""}`;
const cachedData = localStorage.getItem(cacheKey);
if (cachedData) {
return JSON.parse(cachedData);
}
const response = await axios.get(url, {
headers: { "Cache-Control": "max-age=3600" },
});
localStorage.setItem(cacheKey, JSON.stringify(response.data));
return response.data;
},
enabled: !!id,
});
if (isPending) {
return <LoadingPage />;
}
if (error) {
return <ErrorPage />;
}
기존에 axios가 다양한 기능을 지원하고 간단해서 axios를 애용하긴 했는데 next.js 환경에 넘어오면서부터 fetch가 더 코드가 간단해 보이는것은 왜일까..
아직 get 요청에 한해서만 그런건가?
일단은 axios를 썼음
참고
갑자기 무슨 호우경보인지..?
날씨도 흐리고 내 코드들도 흐려지고..