Modules: Komponen Shiny yang Reusable
Penjelasan
Semakin besar aplikasi Shiny, semakin sulit menghindari tabrakan inputId/outputId kalau semua ditulis di satu fungsi server raksasa. Shiny Modules menyelesaikan ini dengan namespacing: sebuah modul terdiri dari fungsi UI (menerima parameter id, membungkus semua inputId/outputId dengan ns <- NS(id) lalu ns("nama")) dan fungsi server (dibungkus moduleServer(id, function(input, output, session) {...})). Karena setiap instance modul punya namespace unik, kamu bisa memanggil modul yang sama berkali-kali (misalnya beberapa 'kartu grafik' identik) tanpa ID-nya saling bentrok — mirip konsep component reusable di framework frontend modern.
Contoh Konsep
library(shiny)
# UI modul
counterUI <- function(id) {
ns <- NS(id)
tagList(
actionButton(ns("tambah"), "Tambah"),
textOutput(ns("nilai"))
)
}
# Server modul
counterServer <- function(id) {
moduleServer(id, function(input, output, session) {
count <- reactiveVal(0)
observeEvent(input$tambah, {
count(count() + 1)
})
output$nilai <- renderText({
paste("Nilai:", count())
})
})
}
# Pakai modul dua kali tanpa bentrok ID
ui <- fluidPage(
counterUI("counter1"),
counterUI("counter2")
)
server <- function(input, output) {
counterServer("counter1")
counterServer("counter2")
}
shinyApp(ui = ui, server = server)
Praktikum
Lengkapi modul UI agar textInput dan textOutput di dalamnya dibungkus namespace ns() dengan benar.
Ketik/edit bebas di sini untuk latihan — kode ini tidak dijalankan.
Tips
Selalu bungkus SETIAP inputId dan outputId di dalam modul UI dengan ns(...) — lupa satu saja membuat ID itu tidak ter-namespace, dan berpotensi bentrok kalau modul dipanggil lebih dari sekali.