- 기본 프로필 이미지 설정
- 프로필 이미지 있을 경우 해당 이미지 표시
- 편집 UI 토글 기능
- 닉네임 수정 기능
- 프로필 이미지 수정 및 미리보기 기능
// 기본 폼 구조
<form onSubmit={handleSubmit}>
<input type="file" onChange={handleFileChange} />
<input
type="text"
value={newName}
onChange={(e) => setNewName(e.target.value)}/>
<button type="button" onClick={handleCancel}>
<button type="submit">수정하기</button>
</div>
</form>
// 이미지 파일 선택 시 이벤트
const handleFileChange = (e) => {
const file = e.target.files[0];
if (file) {
setAvatarFile(file);
if (previewUrl) {
URL.revokeObjectURL(previewUrl);
}
setPreviewUrl(URL.createObjectURL(file));
}
};
// 수정하기 버튼 클릭 시 이벤트
const handleSubmit = async (e) => {
e.preventDefault();
try {
let avatarUrl = user.user_metadata?.avatar_url;
if (avatarFile) {
const fileName = `${user.id}-${Date.now()}`;
const { data, error } = await supabase.storage
.from("avatars")
.upload(fileName, avatarFile);
if (error) throw error;
const {
data: { publicUrl },
} = supabase.storage.from("avatars").getPublicUrl(fileName);
avatarUrl = publicUrl;
console.log("publicUrl", publicUrl);
}
// user테이블 업데이트
const { error } = await supabase
.from("users")
.update({
name: newName,
avatar_url: avatarUrl,
})
.eq("id", user.id);
if (error) throw error;
alert("프로필이 업데이트 되었습니다.");
setIsEditing(false);
setUser({
...user,
name: newName,
avatar_url: avatarFile ? avatarUrl : user.avatar_url,
});
} catch (error) {
console.error(error);
alert("업데이트 실패");
}
};
form의 기본 동작은 제출 시 페이지를 새로고침하면서 서버로 데이터를 전송한다.
SPA에서는 안에있는 코드가 실행되기 전에 페이지가 새로고침된다.
해서 e.preventDefault()를 해서 새로고침을 막아줘야한다.
처음에 file을 e.target.files 형태로 작성했다.
하지만 file을 출력해보면 객체이다.
File {
name: "profile.jpg",
lastModified: ..//
lastModifiedDate: ...
...//
}
위에 name, lastModified... 등이 들어있는 객체이고 내가 필요한 것은 files[0]번째이기 때문에 files[0]을 해야한다.
프로필 이미지 및 닉네임 수정 버튼을 클릭하면
잘 수정되어 supabase의 users테이블에 잘 적용이 되지만
수정 당시 파일 선택 완료 후 아무런 이미지의 변화가 없어서
잘 적용이 되었는지 확인이 어렵다.
supabase의 스토리지에서 .getPublicUrl(fileName)을 사용해서
previewUrl을 사용해서 미리보기 이미지를 생성해서 보여줬더니 잘 확인이 되었다.
브라우저 메모리에 있는 파일에 대한 임시 URL을 생성한다.
생성된 URL의 형태는 보통blob:http://도메인/고유ID형식이다
- 브라우저 메모리에만 존재하는 임시 URL이다.
- 페이지가 닫히면 자동으로 해제된다.
- 다른 탭이나 브라우저에서는 접근할 수 없다.
- 실제 파일 데이터는 브라우저 메모리에 저장된다.
- 사용이 끝난 URL을 해제해줘야한다.
- 해제하지 않으면 메모리 누수가 발생할 수 있다.
- 새 파일이 선택될 때마다 이전 URL을 해제하고 새로운 URL을 생성해야한다.
URL.revokeObjectURL()로 해제 하면된다.
다음은 캠핑 데이터를 페칭 해와서 OPEN API캠핑 데이터를 메인에 뿌려보는걸 해보려고한다.