드로어 컴포넌트 구현 전략
Inertia.js에서 모달(modal) 또는 드로어를 구현하는 세 가지 주요 전략이 있습니다. 첫째, 일반적인 로컬 상태(local state)를 통해 관리하는 방법입니다. 둘째, Inertia UI 라이브러리를 활용하는 방법으로, 모달/드로어를 별도의 페이지처럼 취급하여 고유한 URL과 페이지 객체를 가질 수 있습니다. 셋째, 본 영상에서 중점적으로 다루는 방법으로, 쿼리 파라미터와 Rails 컨트롤러 컨선(concern)을 사용하여 드로어의 상태를 관리하는 방식입니다.
쿼리 파라미터를 활용한 상태 관리
-
링크 클릭 및 쿼리 파라미터 추가: NBA 경기 목록에서 점수 링크를 클릭하면, Inertia.js는 해당 요청을 가로채어 URL에
detailed_game_id라는 쿼리 파라미터를 추가합니다. 이는 일반적인 HTML 앵커 태그처럼 동작하며, Inertia.js가 서버 요청을 처리하고 페이지 응답을 클라이언트 앱에 병합합니다. -
장점: 쿼리 파라미터 방식은 드로어의 상태를 URL에 반영하여, 해당 URL을 새 탭에서 열거나 공유할 때 드로어가 올바른 상태로 열리도록 합니다. 이는 HTML 프로토콜의 기본 원칙을 따르면서 풍부한 클라이언트 측 경험을 제공합니다.
-
Rails 컨트롤러 컨선(
GameDetailable): 서버 측에서는BaseController에GameDetailable컨선을 포함합니다. 이 컨선은detailed_game_id쿼리 파라미터의 존재 여부를 확인하고, 존재할 경우 외부 API에서 실제 경기 상세 데이터를 가져옵니다.inertia_share를 사용하여 이 데이터를 페이지 프롭(page props)으로 공유하며, 쿼리 파라미터 자체도 클라이언트로 다시 전달하여 편의성을 높입니다. -
드로어 컴포넌트 렌더링: 클라이언트 측의
GameDetailsDrawer컴포넌트는 페이지 프롭에서detailed_game_id의 존재 여부를 확인하여 드로어의 열림/닫힘 상태(isDrawerOpen)를 제어합니다. 드로어를 닫을 때는detailed_game_id파라미터 없이 페이지를 다시 로드하여 드로어가 닫히도록 합니다.
낙관적 UI 업데이트 및 사용자 경험 개선
-
문제점: 네트워크 지연(latency)이 발생할 경우, 드로어가 열리거나 닫히는 데 시간이 걸려 사용자 경험이 저하됩니다.
-
낙관적 업데이트 적용: Inertia.js 2.0의 클라이언트 측 방문(client-side visit) 기능을 활용하여, 서버 요청을 보내기 전에 클라이언트에서 페이지 프롭에
detailed_game_id를 낙관적으로 추가합니다. 이를 통해 드로어가 즉시 열리고, 닫을 때도 즉시 닫히는 것처럼 보이게 하여 사용자에게 즉각적인 피드백을 제공합니다. 서버 응답은 백그라운드에서 처리됩니다. -
로딩 상태 표시: 드로어가 열렸지만 아직 상세 데이터가 로드되지 않았을 때(즉,
detailed_game_id는 있지만detailed_game객체는 없을 때) 로딩 스피너를 표시하여 사용자에게 진행 상황을 시각적으로 알립니다. -
오류 처리: 외부 API 호출 시 발생할 수 있는 타임아웃 오류를 시뮬레이션하고,
begin rescue블록으로 이를 처리합니다. 오류 발생 시detailed_game_error라는 새로운 프롭을 클라이언트로 전송하고, 드로어 컴포넌트에서는 이 오류 프롭의 존재 여부를 확인하여 적절한 오류 메시지를 표시합니다.
관심사의 분리 (Separation of Concerns)
이 패턴의 핵심은 각 컴포넌트와 로직이 명확한 책임을 갖는다는 것입니다.
-
GameRow(링크): 단순히detailed_game_id쿼리 파라미터를 서버로 전송하여 “이 게임에 대해 더 알고 싶다”는 의도를 전달할 뿐, UI가 어떻게 반응해야 하는지에 대한 지식은 없습니다. -
Concern(데이터 로딩):detailed_game_id의 존재 여부를 확인하고, 해당 ID를 기반으로 데이터를 로드하거나 오류를 반환합니다. UI에 대한 어떠한 가정도 하지 않습니다. -
GameDetailsDrawer(UI 렌더링): 서버에서 전달된 데이터나 오류를 해석하여 드로어의 열림/닫힘, 로딩 상태, 오류 메시지 표시 등을 결정합니다. 또한, 드로어를 닫는 방법을 스스로 알고 있습니다.
이러한 분리 덕분에, 예를 들어 드로어를 모달이나 페이지 내의 다른 컴포넌트로 변경하더라도 GameRow나 Concern의 코드는 전혀 수정할 필요가 없습니다.