1. Turbo Drive의 기본과 한계
초기 폼은 JavaScript 없이 Turbo Drive를 통해 구현됩니다. Turbo Drive는 <head>
태그 내의 자산과 설정을 유지한 채 <body
> 태그 내용만 교체하여 부드러운 페이지 전환을 제공합니다. 그러나 이는 전체 페이지 탐색을 의미하므로, 폼 제출 시 배경 음악이 끊기는 등 연속적인 사용자 경험을 방해할 수 있습니다.
2. Turbo Frames를 활용한 부분 업데이트
이러한 한계를 극복하기 위해 Turbo Frames가 도입됩니다. <turbo-frame id="..."
> 태그로 특정 영역을 감싸면, 해당 프레임 내부의 콘텐츠만 서버 응답에 따라 교체됩니다. 이는 외부 콘텐츠(예: 배경 음악)를 유지하면서 폼 유효성 검사 오류를 표시하는 등 부분적인 상호작용을 가능하게 하여 사용자 경험의 연속성을 보장합니다. 발표자는 Turbo Frames를 매우 강력하고 깔끔한 해결책으로 평가합니다.
3. Turbo Frames 내 리다이렉트 문제와 해결책
Turbo Frame 내에서 폼 제출 후 다른 페이지로 리다이렉트할 때, 응답에 해당 Turbo Frame이 포함되지 않으면 Turbo가 이를 무시하는 문제가 발생합니다. 기존의 일반적인 해결책은 폼 주변의 Turbo Frame을 제거하고 Turbo Streams로 DOM을 직접 조작하는 것이었으나, 발표자는 이러한 방식이 전체 접근 방식을 변경해야 하므로 비효율적이라고 지적합니다.
대신 발표자는 Turbo Frame을 유지하면서 커스텀 Turbo Stream redirect
액션을 제안합니다. application.js
에 Turbo.StreamActions.redirect = function() { Turbo.visit(this.target); }
를 정의하고, 컨트롤러에서 format.turbo
응답 시 turbo_stream_action_tag("redirect", target: profile_path(@profile))
를 렌더링하여 성공적인 폼 제출 시 전체 페이지 리다이렉트를 수행합니다. 이는 Turbo Frame의 이점을 유지하면서 리다이렉트 문제를 해결하는 우아한 방법입니다.
4. Stimulus와 Turbo Frames를 이용한 실시간 유효성 검사 (Validate on Blur)
현대 웹 애플리케이션에서 흔히 사용되는 블러(blur) 이벤트 기반 유효성 검사 역시 Turbo Streams의 DOM 직접 조작 없이 구현할 수 있습니다. Stimulus 컨트롤러를 사용하여 입력 필드에서 blur
이벤트 발생 시 폼을 validate
플래그와 필드 이름과 함께 제출합니다. 서버 컨트롤러는 이 플래그를 감지하여 해당 필드에 대한 유효성 검사만 수행하고, 폼 전체를 Turbo Frame 내에서 재렌더링합니다. 이 방식은 유효성 검사 로직을 Ruby 서버에 유지하여 유지보수와 테스트를 용이하게 합니다.
5. 점진적 노출 (Progressive Disclosure)
특정 필드의 값에 따라 다른 필드를 동적으로 표시하는 점진적 노출 기능도 Turbo Frames의 재렌더링 메커니즘을 통해 간단히 구현됩니다. 예를 들어, 생년월일 입력에 따라 ‘부모 동의’ 필드를 표시하는 경우, 모델에 underage?
와 같은 헬퍼 메서드를 정의하고 템플릿에서 이 메서드 결과에 따라 조건부로 필드를 렌더링합니다. 블러 이벤트로 폼이 재렌더링될 때 서버의 Ruby 로직이 자동으로 새로운 필드의 표시 여부를 결정합니다. 이로써 추가적인 JavaScript 없이 서버 로직만으로 동적인 UI를 구현할 수 있습니다.