Hotwire는 Rails 애플리케이션의 사용자 경험을 혁신하는 여러 핵심 구성 요소로 이루어져 있습니다.
Hotwire의 주요 구성 요소
-
Turbo Drive: Rails 애플리케이션의 탐색 속도를 향상시키며, 복잡한 클라이언트 측 관리 없이 단일 페이지 애플리케이션(SPA)과 유사한 속도를 제공합니다. 링크 클릭 및 양식 제출을 가로채어 AJAX를 통해 새 콘텐츠를 가져오고, URL을 업데이트하며
head요소를 보존한 채body콘텐츠만 교체하여 전체 페이지 새로고침 없이 빠르고 원활한 전환을 가능하게 합니다. -
Turbo Frames: 웹 페이지를 뉴스 피드, 채팅 창, 장바구니 등 개별 섹션으로 나누는 컨테이너 역할을 합니다. 특정 섹션 내의 콘텐츠가 변경될 때 전체 페이지를 다시 로드하는 대신 해당 섹션만 업데이트하여 성능과 사용자 경험을 크게 향상시킵니다.
-
Turbo Streams: Turbo Frames에서 한 단계 더 나아가 실시간 데이터 업데이트를 가능하게 합니다. 웹소켓(WebSockets) 기술을 활용하여 서버와 브라우저 간 양방향 통신 채널을 통해 새로운 메시지가 즉시 나타나는 라이브 채팅 애플리케이션과 같은 기능을 구현할 수 있습니다.
-
Stimulus: 콘텐츠 업데이트를 담당하는 Turbo Frames 및 Streams와 달리, Stimulus는 웹 페이지에 상호작용성을 추가하는 데 중점을 둡니다. 이는 경량 JavaScript 프레임워크로, 특정 HTML 요소에 사용자 정의 동작을 정의할 수 있게 하여 애니메이션 트리거 버튼, 사용자 입력 유효성 검사 양식 등을 만들 수 있습니다.
Hotwire를 활용한 Rails 애플리케이션 개발 예시
Rails 7에서는 Hotwire가 기본적으로 포함되어 있습니다. rails new my_hotwire_app --css=tailwind --database=postgresql 명령어로 새 Rails 앱을 생성하고, rails g scaffold Blog title:string author:string content:text로 Blog 모델의 스캐폴드를 생성하여 기본적인 CRUD 기능을 구현할 수 있습니다.
-
Turbo Drive 동작 확인: Rails 7에서는 기본적으로 페이지가 Turbo Drive에 의해 구동됩니다. 네트워크 탭에서 XHR 요청을 필터링하면 Turbo Drive가 AJAX 요청을 통해 콘텐츠를 가져오고 전체 페이지 새로고침 없이
body콘텐츠를 교체하는 것을 확인할 수 있습니다.Turbo.session.drive = false설정을 통해 Turbo Drive 없이 동작을 비교할 수 있습니다. -
Turbo Frames를 이용한 생성 (Create) 개선: 기존에는 새 블로그 생성 시 다른 페이지로 리디렉션되었지만, Turbo Frames를 활용하여
app/views/blogs/index.html.erb와app/views/blogs/new.html.erb에turbo_frame_tag "create-blog"를 추가함으로써 새 블로그 양식을 인덱스 페이지 내에 로드할 수 있습니다. 이는 페이지 전환 없이 동일한 페이지에서 양식 상호작용을 가능하게 합니다. -
Turbo Streams를 이용한 생성 (Create) 실시간 업데이트: 새 블로그 생성 후 목록에 즉시 반영되지 않는 문제를 해결하기 위해,
app/controllers/blogs_controller.rb의create액션에format.turbo_stream { render turbo_stream: turbo_stream.prepend("blogs", partial: "blog", locals: { blog: @blog }) }코드를 추가합니다. 이는 성공적인 블로그 생성 시blogsID를 가진 대상 프레임에 새로 생성된 블로그를_blog.html.erb부분 템플릿으로 즉시 추가하여 실시간 업데이트를 제공합니다. -
Turbo Frames를 이용한 업데이트 (Update) 개선: 블로그 개별 항목(
_blog.html.erb)과 편집 양식(edit.html.erb)을turbo_frame_tag dom_id(blog)로 감싸면, 편집 버튼 클릭 시 편집 양식이 인덱스 페이지 내의 해당 블로그 항목 프레임에 로드되어 페이지 이동 없이 편집이 가능해집니다. -
Turbo Streams를 이용한 삭제 (Delete) 실시간 처리: 블로그 삭제 시
app/controllers/blogs_controller.rb의destroy액션에format.turbo_stream { render turbo_stream: turbo_stream.remove(@blog) }를 추가하면, 해당 블로그가 목록에서 부드럽게 제거되어 사용자 경험을 향상시킵니다.