Vue 3 프로젝트에서 ref와 함수 바인딩 문제 해결: Vuex/Pinia와의 통합

YuJun Oh·2024년 8월 28일
0

배경: 문제 상황 인식

최근 진행 중이던 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의 반응성이 제대로 작동하지 않았습니다. 특히, serviceDataListtotalServiceData와 같은 상태가 변경되어도 컴포넌트가 이를 감지하지 못해 화면에 반영되지 않는 문제가 발생했습니다.

시도해봤던 해결 방법

  1. 데이터 업데이트 확인:
    먼저, 데이터를 제대로 가져오고 있는지 확인했습니다. 콘솔 로그를 통해 데이터가 제대로 API에서 반환되는지, 그리고 Vue 컴포넌트 내의 상태가 업데이트되는지를 체크했습니다. 이 과정에서 데이터를 제대로 받아오고 있지만 화면에 반영되지 않는다는 것을 확인했습니다.

  2. Vuex/Pinia의 상태 관리 구조 점검:
    다음으로, Vuex 또는 Pinia와 같은 상태 관리 라이브러리에서 상태를 제대로 관리하고 있는지 확인했습니다. 상태를 관리하는 스토어 코드가 올바른지, 상태가 변경될 때 Vue 컴포넌트가 이를 반응적으로 감지할 수 있는지를 검토했습니다.

  3. watch와 같은 리액티브 헬퍼 사용:
    데이터를 수동으로 감시하고 업데이트할 수 있도록 watch를 사용해보기도 했습니다. 하지만 이 방법은 근본적인 해결책이 되지 않았고, 코드가 복잡해지는 결과를 초래했습니다.

  4. 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을 업데이트하게 되었습니다. 그 결과, 화면에서 데이터를 올바르게 표시할 수 있었습니다.

중요한 교훈

이번 문제를 통해 얻은 교훈은 다음과 같습니다:

  1. Vue 3의 반응성 이해: Vue 3에서 ref, reactive, computed 등의 반응성을 제대로 이해하는 것이 중요합니다. 상태가 언제 반응적으로 작동하는지, 그리고 어떻게 바인딩하는지가 컴포넌트 동작의 핵심입니다.

  2. storeToRefs의 필요성: Vuex나 Pinia와 같은 상태 관리 라이브러리에서 상태를 가져올 때, storeToRefs를 사용해 상태를 ref로 감싸는 것이 필수적입니다. 이를 통해 Vue가 상태 변경을 감지하고 DOM을 자동으로 업데이트할 수 있습니다.

  3. 코드 구조의 명확성: 상태와 메서드를 명확하게 구분하여 사용하는 것이 중요합니다. 상태는 반응성을 유지해야 하며, 메서드는 그대로 사용해야 합니다. 이를 명확히 구분하지 않으면, Vue의 반응성 시스템이 제대로 동작하지 않을 수 있습니다.

  4. 디버깅의 중요성: 문제가 발생했을 때, 콘솔 로그를 사용해 데이터를 확인하고, 데이터 흐름을 추적하는 것이 문제 해결의 중요한 단서가 될 수 있습니다.

결론

Vue 3 프로젝트에서 상태 관리와 관련된 문제를 해결하기 위해서는 Vue의 반응성 시스템을 잘 이해하고, 올바르게 적용하는 것이 중요합니다. 특히, 상태 관리 라이브러리와 통합할 때 storeToRefs를 사용해 상태를 ref로 감싸는 방법을 기억해야 합니다.

이 경험을 통해 더욱 안정적이고 효율적인 Vue 애플리케이션을 만들 수 있을 것이며, 상태 관리와 반응성 문제를 더 잘 이해하게 되었습니다. 앞으로 유사한 문제를 겪게 될 때 이 경험이 큰 도움이 될 것이라고 생각합니다.

0개의 댓글

관련 채용 정보