최근 진행 중이던 Vue 3 프로젝트에서, Vuex 또는 Pinia와 같은 상태 관리 라이브러리를 사용해 데이터를 관리하는 과정에서, 상태가 제대로 반영되지 않는 문제에 직면했습니다. 특히, 컴포넌트에서 데이터가 화면에 표시되지 않거나, 업데이트된 데이터가 DOM에 반영되지 않는 현상이 발생했습니다.
이 문제는 데이터가 콘솔에서는 정상적으로 출력되지만, 실제 화면에서는 여전히 초기값만 표시되거나 빈 배열로 나타나는 등, 의도한 대로 동작하지 않는 경우였습니다. 특히, {{ totalServiceData }}
와 {{ serviceDataList }}
로 바인딩한 데이터가 화면에 표시되지 않는 문제로 고생했습니다.
Vue 3의 setup
함수 안에서 상태를 바인딩하는 방식에 대한 이해가 부족한 것이 문제의 원인이었습니다. Vue 3에서는 컴포넌트 내부에서 스토어의 상태와 메서드를 가져와 사용할 때 storeToRefs
를 통해 상태를 ref
로 감싸는 것이 중요합니다.
처음에 저는 아래와 같은 방식으로 상태와 메서드를 함께 가져와 사용했습니다:
const {
serviceDataList,
totalServiceData,
currentPage,
totalPages,
sortField,
sortOrder,
serviceFilter,
hospitalFilter,
departmentFilter,
startDate,
endDate,
recordingTimeMin,
recordingTimeMax,
userIdFilter,
getServiceDataList,
changePage,
changeSort,
deleteServiceData
} = store;
이 방식에서는 상태와 메서드를 함께 가져와 사용했기 때문에, Vue의 반응성이 제대로 작동하지 않았습니다. 특히, serviceDataList
나 totalServiceData
와 같은 상태가 변경되어도 컴포넌트가 이를 감지하지 못해 화면에 반영되지 않는 문제가 발생했습니다.
데이터 업데이트 확인:
먼저, 데이터를 제대로 가져오고 있는지 확인했습니다. 콘솔 로그를 통해 데이터가 제대로 API에서 반환되는지, 그리고 Vue 컴포넌트 내의 상태가 업데이트되는지를 체크했습니다. 이 과정에서 데이터를 제대로 받아오고 있지만 화면에 반영되지 않는다는 것을 확인했습니다.
Vuex/Pinia의 상태 관리 구조 점검:
다음으로, Vuex 또는 Pinia와 같은 상태 관리 라이브러리에서 상태를 제대로 관리하고 있는지 확인했습니다. 상태를 관리하는 스토어 코드가 올바른지, 상태가 변경될 때 Vue 컴포넌트가 이를 반응적으로 감지할 수 있는지를 검토했습니다.
watch
와 같은 리액티브 헬퍼 사용:
데이터를 수동으로 감시하고 업데이트할 수 있도록 watch
를 사용해보기도 했습니다. 하지만 이 방법은 근본적인 해결책이 되지 않았고, 코드가 복잡해지는 결과를 초래했습니다.
onMounted
에서 데이터 초기화 재시도:
컴포넌트가 마운트될 때마다 데이터를 새로 가져오도록 했지만, 여전히 반응성 문제는 해결되지 않았습니다.
문제를 해결할 수 있는 단서가 된 것은 Vue 3의 storeToRefs
헬퍼 함수였습니다. storeToRefs
는 상태 관리 라이브러리의 상태를 ref
로 변환하여 반응성을 유지할 수 있도록 도와줍니다.
해결 방법은 스토어에서 가져오는 상태와 메서드를 명확히 구분하는 것이었습니다. storeToRefs
를 사용해 상태를 ref
로 감싸고, 메서드는 그대로 사용하는 방식으로 코드를 수정했습니다.
import { storeToRefs } from 'pinia'; // Vuex 사용 시에는 이 부분을 Vuex 관련 헬퍼로 변경
const {
serviceDataList, // 상태는 storeToRefs로 가져옴
totalServiceData,
currentPage,
totalPages,
sortField,
sortOrder,
serviceFilter,
hospitalFilter,
departmentFilter,
startDate,
endDate,
recordingTimeMin,
recordingTimeMax,
userIdFilter
} = storeToRefs(store);
const {
getServiceDataList, // 메서드는 그대로 가져옴
changePage,
changeSort,
deleteServiceData,
getServiceDataDetail
} = store;
이렇게 코드를 수정한 후, 상태가 정상적으로 반영되기 시작했습니다. storeToRefs
는 상태 관리 라이브러리에서 가져온 상태를 ref
로 감싸서 컴포넌트가 상태 변경을 반응적으로 감지할 수 있게 해주었습니다.
이 방법으로 컴포넌트는 상태가 변경될 때마다 자동으로 DOM을 업데이트하게 되었습니다. 그 결과, 화면에서 데이터를 올바르게 표시할 수 있었습니다.
이번 문제를 통해 얻은 교훈은 다음과 같습니다:
Vue 3의 반응성 이해: Vue 3에서 ref
, reactive
, computed
등의 반응성을 제대로 이해하는 것이 중요합니다. 상태가 언제 반응적으로 작동하는지, 그리고 어떻게 바인딩하는지가 컴포넌트 동작의 핵심입니다.
storeToRefs
의 필요성: Vuex나 Pinia와 같은 상태 관리 라이브러리에서 상태를 가져올 때, storeToRefs
를 사용해 상태를 ref
로 감싸는 것이 필수적입니다. 이를 통해 Vue가 상태 변경을 감지하고 DOM을 자동으로 업데이트할 수 있습니다.
코드 구조의 명확성: 상태와 메서드를 명확하게 구분하여 사용하는 것이 중요합니다. 상태는 반응성을 유지해야 하며, 메서드는 그대로 사용해야 합니다. 이를 명확히 구분하지 않으면, Vue의 반응성 시스템이 제대로 동작하지 않을 수 있습니다.
디버깅의 중요성: 문제가 발생했을 때, 콘솔 로그를 사용해 데이터를 확인하고, 데이터 흐름을 추적하는 것이 문제 해결의 중요한 단서가 될 수 있습니다.
Vue 3 프로젝트에서 상태 관리와 관련된 문제를 해결하기 위해서는 Vue의 반응성 시스템을 잘 이해하고, 올바르게 적용하는 것이 중요합니다. 특히, 상태 관리 라이브러리와 통합할 때 storeToRefs
를 사용해 상태를 ref
로 감싸는 방법을 기억해야 합니다.
이 경험을 통해 더욱 안정적이고 효율적인 Vue 애플리케이션을 만들 수 있을 것이며, 상태 관리와 반응성 문제를 더 잘 이해하게 되었습니다. 앞으로 유사한 문제를 겪게 될 때 이 경험이 큰 도움이 될 것이라고 생각합니다.