February 07, 2023
vue3의 composition api를 사용하면 로직을 재사용할 수 있습니다.
직접 짜보니 react hook과 흡사하다는 생각이 많이 들었습니다.
supabase에서 id에 해당하는 data의 한글이름을 가져오는 코드를 재사용하기 위해 짜보았습니다.
// @/modules/useKoreanName.js
import { supabase } from '@/utils/supabase'
import { reactive, toRefs } from 'vue'
export default function useUserKoreanName() {
const state = reactive({
userKoreanName: '이름',
})
const loadUserKoreanName = async id => {
const koreanName = await fetchUserKoreanName(id)
if (koreanName) state.userKoreanName = koreanName
}
const fetchUserKoreanName = async id => {
try {
const { data: users } = await supabase
.from('users')
.select('korean_name')
.eq('id', id)
if (users) {
return users[0].korean_name
}
} catch (error) {
console.error(error)
}
}
return { ...toRefs(state), fetchUserKoreanName, loadUserKoreanName }
}
여기서 눈여겨볼 점은 state를 ...toRefs(state)
의 형태로 반환하는 점입니다. 이렇게 해야 반응성이 유지된다고 하는데요. 이 모듈을 컴포넌트에서 불러와서 사용해봤습니다.
const { userKoreanName, loadUserKoreanName } = useKoreanName();
onMounted(() => {
fetchNotes();
loadUserKoreanName(id);
});
...
<div class="text-4xl mr-4">{{ userKoreanName }} 님 담벼락</div>
template에서 userKoreanName을 출력하는데 아래와 같이 잘 동작하는 것을 볼 수 있습니다.
만약에 toRefs를 빼보면 어떨까요?
// @/modules/useKoreanName.js
import { supabase } from '@/utils/supabase'
import { reactive } from 'vue'
export default function useUserKoreanName() {
const state = reactive({
userKoreanName: '이름',
})
const loadUserKoreanName = async id => {
const koreanName = await fetchUserKoreanName(id)
if (koreanName) state.userKoreanName = koreanName
console.info('koreanName after load : ', state.userKoreanName)
}
const fetchUserKoreanName = async id => {
try {
const { data: users } = await supabase
.from('users')
.select('korean_name')
.eq('id', id)
if (users) {
return users[0].korean_name
}
} catch (error) {
console.error(error)
}
}
return { ...state, fetchUserKoreanName, loadUserKoreanName }
}
이 경우에는 로그를 찍어보면 useUserKoreanName 함수 내부에서는 state가 반응성을 띕니다.
하지만 컴포넌트에서 userKoreanName을 출력해보면 기본값이 들어가 있는 것을 확인할 수 있습니다.
toRefs에 관한 공식문서
공식문서를 살펴보면 toRefs
는 composable function에서 반응형의 객체를 반환할 때, 사용하는 컴포넌트에서는 객체를 destructure나 spread를 하더라도 반응성을 잃지 않도록 한다고 합니다.