- 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와 분명한 병합 로직을 함께 쓰면서 데이터 불일치를 잡았고, 좀 더 안정적인 애플리케이션 환경을 만들 수 있었습니다. 앞으로도 사용자 경험을 끌어올리려고 계속 문제를 분석하고 개선해 나갈 생각입니다.