Shiny · R · cheat sheet

Shiny module state patterns

Where state lives decides how a Shiny app grows. Two patterns cover most modules; both are tested here with shiny::testServer, the way a module should be tested before it ships.

Download the PDFAll cheat sheets

RPattern 1: the module returns its state. Tested with testServer.

library(shiny)

counter_server <- function(id, step = reactive(1)) {
  moduleServer(id, function(input, output, session) {
    total <- reactiveVal(0)
    observeEvent(input$add, total(total() + step()))
    total    # the caller reads this reactive
  })
}

testServer(counter_server, args = list(step = reactive(2)), {
  session$setInputs(add = 1)
  session$setInputs(add = 2)
  stopifnot(session$returned() == 4)
  cat("returned after two clicks with step 2:", session$returned(), "\n")
})

Ran when this sheet was built. Output:

returned after two clicks with step 2: 4

RPattern 3: per-session shared state through session$userData.

library(shiny)

picks_server <- function(id) {
  moduleServer(id, function(input, output, session) {
    if (is.null(session$userData$picks)) session$userData$picks <- reactiveVal(character())
    observeEvent(input$pick, session$userData$picks(c(session$userData$picks(), input$pick)))
  })
}

testServer(picks_server, {
  session$setInputs(pick = "FF")
  session$setInputs(pick = "SL")
  cat("shared picks:", session$userData$picks(), "\n")
})

Ran when this sheet was built. Output:

shared picks: FF SL