Consider the below sample application demonstrating two ways to show UI based on a condition:
library(shiny)
ui <- fluidPage(
tagList(
checkboxInput("toggle", "Toggle"),
conditionalPanel(
condition = "output.condition",
tags$p("Output from conditionalPanel")
),
uiOutput("ui")
)
)
server <- function(input, output, session) {
# conditionalPanel
output$condition <- reactive(input$toggle)
outputOptions(output, "condition", suspendWhenHidden = FALSE)
# uiOutput
output$ui <- renderUI({
req(isTRUE(input$toggle))
tags$p("Output from uiOutput")
})
}
shinyApp(ui, server)
In terms of the front-end, the conditionalPanel and uiOutput/req patterns seem to behave similarly. Are there any differences, especially related to performance, that would make one pattern more beneficial?
These two ways do have different purposes. conditionalPanel creates a JavaScript expression which "listens" for a specific condition, e.g. whether an input is TRUE or FALSE. Nothing needs to happen on the server-side.
renderUI() in contrast is very flexible. Of course, it can mimic the behavior of conditionalPanel but is also capable to output basically anything by creating different HTML (UI) code.
Regarding speed: conditionalPanel should almost always be faster. Additionally, not performance should be the decider between both options but the goal should.
library(shiny)
ui <- fluidPage(
tagList(
checkboxInput("toggle", "Toggle"),
conditionalPanel(
# listens whether toggle is TRUE or FALSE
condition = "input.toggle",
tags$p("Output from conditionalPanel")
),
uiOutput("ui")
)
)
server <- function(input, output, session) {
# create a plot
output$myplot <- renderPlot({
plot(mtcars$mpg, mtcars$cyl)
})
# create some text
output$mytext <- renderText({
"I am pointless"
})
# uiOutput
output$ui <- renderUI({
input$toggle
if (rnorm(1) > 0){
plotOutput("myplot")
} else {
textOutput("mytext")
}
})
}
shinyApp(ui, server)