Supabase를 사용하여 데이터를 가져온 후, 변경된 값을 업데이트할 수 있습니다. 그러나 데이터 객체를 직접 수정하기보다는 새로운 객체를 만들어서 업데이트하는 것이 더 안전합니다. 다음은 그 예제입니다:
- 데이터를 가져와 필요한 필드를 업데이트합니다.
- 업데이트된 데이터를 Supabase를 통해
upsert
로 저장합니다.
아래는 코드 예제입니다:
import { useState, useEffect } from 'react';
import { createClient } from '@supabase/supabase-js';
import { Tables } from '@/types/supabase.ts'
import useAuth from "@/context/auth.context.ts"
const supabase = createClient('your-supabase-url', 'your-supabase-anon-key');
type User = Tables<"users">;
function UserProfile() {
const { me } = useAuth();
const [profileImg, setProfileImg] = useState<string>('/default-image.png')
const [nickname, setNickname] = useState<string | null>(null);
const [avatarFile, setAvatarFile] = useState<File | null>(null);
const [introduction, setIntroduction] = useState<string | null>(null);
const dataRef = useRef<User | null>(null);
const handleSubmit = async () => {
const updatedFields: Record<string, any> = {};
if (avatarFile !== null) {
const fileName = `avatars_${me.id}.jpg`;
const { error } = await supabase
.storage
.from('profile')
.upload(fileName, avatarFile, {
cacheControl: '3600',
upsert: true
});
// 실제로는 아래처럼 그냥 리턴시키시보다는 뭔가 로직이 필요할 것 같습니다.
if(error) return;
const { data } = supabase
.storage
.from('profile')
.getPublicUrl(fileName);
updatedFields.avatarFile = data.publicUrl;
// optimstic update ?
setProfileImage(data.publicUrl);
}
if (nickname !== null) updatedFields.nickname = nickname;
if (introduction !== null) updatedFields.introduction = introduction;
const updatedData = {
...dataRef.current,
...updatedFields,
};
const { data, error: updateError } = await supabase
.from('users')
.upsert(updatedData)
.select();
if (updateError) {
console.error(updateError);
return;
}
setProfileImg(data.avatar);
setNickname(data.nickname);
setIntroduction(data.introduction);
console.log('User updated:', data);
};
useEffect(() => {
const fetchUserData = async () => {
const { data, error } = await supabase
.from('users')
.select('*')
.eq('id', me.id)
.single();
if (error) {
console.error(error);
return;
}
dataRef.current = data;
setProfileImg(data.avatar);
setNickname(data.nickname);
setIntroduction(data.introduction);
};
fetchUserData();
}, []);
return (
<div>
<img src={profileImg} alt="profile-image" />
<input
type="text"
value={nickname ?? ''}
onChange={(e) => setNickname(e.target.value)}
placeholder="Nickname"
/>
<input type="file" onChange={(e) => setAvatarFile(e.target.files?.[0] ?? null)} />
<textarea
value={introduction ?? ''}
onChange={(e) => setIntroduction(e.target.value)}
placeholder="Introduction"
/>
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
export default UserProfile;
- 데이터 가져오기:
fetchUserData
함수는 현재 유저 데이터를 가져와서 로컬 상태를 설정합니다. - 상태 업데이트: 각 입력 필드가 변경될 때마다 로컬 상태를 업데이트합니다.
- 업데이트할 필드 준비:
handleSubmit
함수는 변경된 필드만 모아서updatedFields
객체를 만듭니다. - 기존 데이터와 병합: 기존 데이터를 가져와
updatedFields
와 병합합니다. - 데이터 업데이트:
upsert
를 사용하여 업데이트된 데이터를 Supabase에 저장합니다.
이 방식으로 기존 데이터와 변경된 데이터를 안전하게 병합하고, 필요한 필드만 업데이트할 수 있습니다.
'supabase' 카테고리의 다른 글
[240808 TIL] 테이블 join 해서 가져오기 (0) | 2024.08.08 |
---|---|
[240806 TIL] 쿠키 배달 fetch(supabase auth) (0) | 2024.08.06 |
[240729 TIL] 수파베이스 리얼타임(테이블저장) (0) | 2024.07.29 |
[240728 TIL] naver 로그인 편법 구현 with Supabase 2편 (0) | 2024.07.28 |
[240727 TIL] naver 로그인 편법 구현 with Supabase 1편 (0) | 2024.07.28 |