
이어하기 기능을 제공하고자 함이어하기 기능 제공우리의 서비스는 실제와 같은 면접 방식을 제공하는 것이 중요하기에 후자의 서비스 방식을 채택하게됨
진행 중이라고 저장진행 중 면접 기록을 제공사용자가 면접을 완료하지 않고 페이지를 나갈 때를 포착한다면, 그 시점에 상태를 저장하고 기록을 변경하도록 하면 되기 때문에 UseEffect 의 CleanUp을 활용하여 Unmounted 시점에 데이터 처리로직을 구현하는 방식으로 이어 하기 기능을 제공하고자 했다.

기능 구현 시, 질문 초기화, 페이지를 나갔음에도 재생되는 음성 등 매우 크리티컬한 문제들이 존재했다. 이 중 중요하게 생각하는 내용 2개를 설명 하려고 한다.
해당 페이지는 prefetch를 통해 면접 기록을 받아온다. 그렇다면 페이지 이탈 혹은 면접 완료 시 해당 쿼리키로 저장돼있는 데이터를 mutate를 통해서 변경해야 한다. 그렇기 때문에 클린업 함수에 Mutate를 실행하여 해당 로직이 동작하도록 구현했다.
그러나 면접 이탈 이후에 면접 페이지 진입 시 데이터의 변경이 일어나지 않고 있었다.

서버에게 면접 상태 변경 요청 이후 성공 시( onSuccess() ), 쿼리키의 무효화 및 삭제 요청을 보내 면접페이지에 반영되도록 설계했다.
실제로 다른 페이지 이동 이후 면접 페이지로 접근했을 땐 변경된 데이터를 확인할 수 있었지만, 진행 중 곧바로 선택 페이지로 접근했을 때는 데이터를 가져오지 못하는 것을 확인했다.
이 부분을 찾다보니 onSuccess나 onError의 시점을 mutationFn 이 실행된 직후라고 보장할 수 없다는 것을 확인했다.
해당 내용은 JS의 이벤트 루프와 비동기 처리를 위한 두 가지 큐를 확인할 수 있었다.
setTimeout, setInterval, DOM events 등을 관리하는 Task Queue 그리고 Promises, MutationObserver, queueMicrotask 등을 관리하는 Microtask Queue가 존재한다.
이 때 Microtask가 항상 Task보다 먼저 실행되는데
실제 흐름 순서는
unmounted() 클린업 함수 호출patchInterviewHistoryMutate() 실행mutation이므로 내부적으로 Promise가 만들어짐 실제 서버 요청은 백그라운드에서 비동기적으로 처리됨onSuccess는 .then()에 등록된 Microtask로 마이크로태스크 큐에 들어감unmounted()는 여전히 async이긴 해도, 내부 await이 끝날 때까지 기다리지 않고 이후 작업(컴포넌트 언마운트) 로 넘어감 -> 문제 발생 지점onSuccess()를 실행React는 useEffect의 cleanup 함수가 비동기임에도 Promise를 기다리지 않는 이유는
해당 이유로 onSuccess의 동작이 완료되지 않은 채로 면접 선택 페이지로 이동하게 된 것이다.
UseMutate에는 비동기적인 처리를 위한 mutateAsync 함수가 존재하는데 해당 로직을 이용하여 unmount에서 직접 await를 명시하여 쿼리키 데이터에 대한 무효화 처리를 진행했다.

뒤로 가기 시 면접 데이터 미반영앞에서 말한 내용처럼 면접 도중에 페이지를 나가게 됐을 때 MutateAsync를 통해 비동기 처리와 쿼리키 무효화를 진행했다.
그러나 뒤로 가기로 면접 진행 페이지로 접근 시 이전까지 진행된 면접 데이터를 가져오지 못하는 것을 확인했다.
이에 대해서 처음엔 사용자의 뒤로 가기를 통한 면접 진행 페이지 접근을 막고자 했다. 실제로 우리가 설계한 user flow에서는 면접 진행 페이지는 무조건 면접관 선택 페이지를 거쳐야 들어갈 수 있었다.
사용자의 router queue를 확인하여 Navigation Type이 POP인 것을 확인하고자 했다. 그러나 Next 환경에서는 사용할 수 없는 방법이였다.
그래서 이번에는 면접 진행 페이지에 들어올 때마다 onPopstate 이벤트 리스너를 추가하여 뒤로 가기에서 접근을 막도록 구현했다.

그러나 해당 방식은 면접 진행 페이지에 계속해서 접근하고 뒤로 가기 동작이 없다면 심각한 메모리 누수가 생길 수 있다. (이벤트 리스너가 계속해서 추가되고 제거되지 않기 때문에)
언마운트 시 서버로 전송한 데이터를 면접 선택 페이지에서 다시 fetch해야 하는데 그 과정없이 면접을 진행하려고 하니 정상 데이터로 진행하지 못한 것이다.
결과적으로 서버로 데이터를 받아오는 과정이 생긴다면 뒤로 가기에도 이어할 수 있게 되는 것이다.
그래서 데이터 fetching 함수를 새롭게 구현해야하나 생각하던 도중에 페이지 이동 시 리렌더링이 일어나면 데이터를 fetching 하는 과정도 다시 진행된다라는 점을 활용하여 아주 간단하게 문제를 해결했다.
async-await 처리와 router.refresh() 호출 시점을 명확히 설계함으로써, 데이터 요청부터 화면 표시까지 일관된 흐름을 보장할 수 있음을 확인하였습니다.