Shiny · R · cheat sheet
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.
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