Reactive Recap
Let’s recap what we have learned about reactivity and discuss best practices.
Three Lessons
There are three main takeaway messages about reactivity that all Shiny developers should be familiar with.
- Reactives are like functions, but they are lazily evaluated, meaning they will only evaluate when their inputs change, not each time they are called.
- Reactive inputs and expressions are for their values and observers are for their side effects.
- Do not define a
reactive()
inside arender*()
function.
What’s wrong?
We’ll wrap up the chapter with a simple but important example.
Here we have an app that adds 2 to the current value of x.
library(shiny)
library(bslib)
<- page_sidebar(
ui title = "Add 2",
sidebar = sliderInput("x", "Select x", min = 1, max = 50, value = 30),
textOutput("x_updated")
)
<- function(input, output, session) {
server <- function(x) {
add_2 + 2
x
}<- add_2(input$x)
current_x $x_updated <- renderText({
output
current_x
})
}
shinyApp(ui, server)
Here is what the app should look like:
And here again is the code. What’s wrong here?
library(shiny)
<- page_sidebar(
ui title = "Add 2",
sidebar = sliderInput("x", "Select x", min = 1, max = 50, value = 30),
textOutput("x_updated")
)
<- function(input, output, session) {
server <- function(x) {
add_2 + 2
x
}<- add_2(input$x)
current_x $x_updated <- renderText({
output
current_x
})
}
shinyApp(ui, server)
The object current_x
is used in the render function, but it’s not currently a reactive expression.
So we need to put the definition of current_x
in the reactive function, like this:
library(shiny)
library(bslib)
<- page_sidebar(
ui title = "Add 2",
sidebar = sliderInput("x", "Select x", min = 1, max = 50, value = 30),
textOutput("x_updated")
)
<- function(input, output, session) {
server <- function(x) {
add_2 + 2
x
}<- reactive({
current_x add_2(input$x)
})$x_updated <- renderText({
output
current_x
})
}
shinyApp(ui, server)
But that’s still not enough…
We also need to refer to current_x
with parantheses after its name.
library(shiny)
library(bslib)
<- page_sidebar(
ui title = "Add 2",
sidebar = sliderInput("x", "Select x", min = 1, max = 50, value = 30),
textOutput("x_updated")
)
<- function(input, output, session) {
server <- function(x) {
add_2 + 2
x
}<- reactive({
current_x add_2(input$x)
})$x_updated <- renderText({
outputcurrent_x()
})
}
shinyApp(ui, server)
Missing the parentheses is a common error when working with reactives. So add this to your list! When developing Shiny apps, be wary of missing commas, and of missing parentheses when calling reactive expressions.
Practice - What’s wrong?
Your turn
- What’s wrong with this? Fix it.
Complete the exercise by navigating to the Posit Cloud Project titled 3-5 Whats wrong in your Posit Cloud Workspace
# Load packages ----------------------------------------------------------------
library(shiny)
library(bslib)
# Define UI --------------------------------------------------------------------
<- page_sidebar(
ui title = "Multiply by 3",
sidebar = sliderInput("x", "Select x", min = 1, max = 50, value = 30),
textOutput("x_updated")
)
# Define server ----------------------------------------------------------------
<- function(input, output, session) {
server
<- function(x) {
mult_3 * 3
x
}$x_updated <- mult_3(input$x)
output
}
# Create the Shiny app ---------------------------------------------------------
shinyApp(ui, server)
# Load packages ----------------------------------------------------------------
library(shiny)
# Define UI --------------------------------------------------------------------
<- page_sidebar(
ui title = "Multiply by 3",
sidebar = sliderInput("x", "Select x", min = 1, max = 50, value = 30),
textOutput("x_updated")
)
# Define server ----------------------------------------------------------------
<- function(input, output, session) {
server <- function(x) {
mult_3 * 3
x
}<- reactive({
current_x mult_3(input$x)
})$x_updated <- renderText({
outputcurrent_x()
})
}
# Create the Shiny app ---------------------------------------------------------
shinyApp(ui = ui, server = server)