- Published on
일정 관리와 데이터 동기화 문제 해결하기
- Authors
- Name
- Hyo814
배경
최근 일정 관리 애플리케이션에서 일정 데이터와 여행 경로 데이터를 동기화하는 과정에서 다양한 문제가 발생했습니다. 특히 과거 데이터를 제대로 병합하지 못해 데이터 매칭 오류가 빈번하게 발생했으며, 이는 사용자 경험에 큰 영향을 미쳤습니다. 이 글에서는 이러한 문제를 어떻게 분석하고 해결했는지 정리해 보겠습니다.
문제 정의
- 과거 데이터와 새로운 데이터의 병합 오류
- 과거 데이터를 무시한 채 새 데이터를 추가하는 방식으로 인해 데이터 불일치 현상이 발생.
- 삭제된 데이터를 병합에서 제외하지 못해 UI에 표시되는 데이터와 실제 데이터가 불일치.
- 무한 스크롤에서 데이터 매칭 문제
- React Query를 사용하여 무한 스크롤을 구현했지만, 병합 로직이 제대로 관리되지 않아 데이터가 중복되거나 누락.
- 상태 관리와 동기화 문제
- 삭제된 장소 데이터(
deletedPlaces
)가 동기화되지 않아 삭제 처리가 제대로 이루어지지 않음. - 상태 관리 파일(src/store/scheduleStore.ts)에서
fetchAndMergeRoutes
와 관련된 로직 오류.
- 삭제된 장소 데이터(
문제 해결 과정
1. 과거 데이터와 새로운 데이터 병합 로직 수정
기존 병합 로직에서는 과거 데이터를 충분히 고려하지 않았습니다. 이에 따라 데이터 병합 로직을 아래와 같이 수정하였습니다.
fetchAndMergeRoutes: async (scheduleId: number) => {
try {
let currentPage = 1;
let totalPages = 1;
let allRoutes: Place[] = [];
while (currentPage <= totalPages) {
const response = await fetchTravelRoute(scheduleId, currentPage);
if (response.success) {
const { data } = response;
totalPages = data.totalPages;
allRoutes = [...allRoutes, ...data.content];
currentPage++;
} else {
console.error(`[fetchAndMergeRoutes] 페이지 ${currentPage} 조회 실패`);
break;
}
}
set((state) => {
const mergedRoutes = [
...allRoutes.filter(
(newRoute) =>
!state.travelRoute.some(
(route) => route.placeId === newRoute.placeId,
) &&
!state.deletedPlaces.includes(newRoute.placeId),
),
...state.travelRoute,
];
return {
travelRoute: mergedRoutes,
addedPlaces: mergedRoutes.map((route) => ({
placeId: route.placeId,
lat: route.latitude,
lng: route.longitude,
})),
};
});
} catch (error) {
console.error('[fetchAndMergeRoutes] 오류 발생:', error);
}
};
2. React Query를 활용한 서버 상태 관리
React Query를 도입하여 서버 상태를 효율적으로 관리하고, 데이터 불일치 문제를 최소화했습니다. 이를 통해 다음과 같은 장점을 얻을 수 있었습니다:
- 자동 캐싱 및 리패칭: 데이터 변경 시 최신 상태 유지.
- 병렬 데이터 요청: 네트워크 성능 최적화.
- 명시적 에러 핸들링: 오류 상황에 대한 상세한 로그 기록.
3. 삭제 데이터 동기화
deletedPlaces
상태가 제대로 반영되지 않아 발생한 문제를 해결하기 위해 삭제 데이터 동기화 로직을 추가로 구현하였습니다. 삭제된 데이터를 병합에서 제외하는 필터링 과정을 명확히 정의했습니다.
const mergedRoutes = [
...allRoutes.filter(
(newRoute) =>
!state.travelRoute.some((route) => route.placeId === newRoute.placeId) &&
!state.deletedPlaces.includes(newRoute.placeId)
),
...state.travelRoute,
]
4. 오류 타입 명시화
JavaScript에서 any
타입 사용을 최소화하고, Error
타입을 명확히 지정하여 디버깅 시간을 단축했습니다.
try {
// 로직 실행
} catch (error: unknown) {
if (error instanceof Error) {
console.error('[fetchAndMergeRoutes] 오류 발생:', error.message);
}
}
결과
위의 수정 사항을 반영한 후, 아래와 같은 개선 효과를 확인할 수 있었습니다:
- 과거 데이터와 새로운 데이터가 올바르게 병합됨.
- 삭제된 데이터가 UI와 백엔드 상태 모두에서 정확히 반영됨.
- React Query를 활용한 서버 상태 관리로 데이터 불일치 문제 해결.
- 명시적 에러 핸들링으로 디버깅 효율 향상.
결론
이번 작업을 통해 상태 관리와 데이터 동기화의 중요성을 다시 한번 실감할 수 있었습니다. 특히, React Query와 명확한 병합 로직을 사용함으로써 데이터 불일치 문제를 해결하고, 보다 안정적인 애플리케이션 환경을 제공할 수 있었습니다. 앞으로도 사용자 경험을 개선하기 위해 지속적으로 문제를 분석하고 개선해 나갈 것입니다.