Basic Reactivity

Lecture 20

Dr. Eric Friedlander

College of Idaho
CSCI 2025 - Winter 2026

The Server Function

Overview

  • Frontend: ui object (HTML).
  • Backend: server function (Logic).
    • Invoked once per session.
    • Creates a new local environment for each user.
    • Isolates variables between sessions.
server <- function(input, output, session) {
  # Logic goes here
}

Input

  • input: List-like object representing data sent from the browser.
  • Read-only: Can’t modify it directly (e.g., input$x <- 5 throws an error).
  • Selective access: Can only read input inside a reactive context (e.g., render* functions or reactive()).
# Error: Can't access reactive value 'count' outside of reactive consumer
message(input$count) 

# OK
renderText({ message(input$count) })

Output

  • output: List-like object for sending data to the browser.
  • Usage: output$ID <- render*({ ... }).
    • Sets up a reactive context.
    • Converts R code to HTML.
  • Rules:
    • Must use a render function.
    • Can only access in the server function.

Reactive Programming

The Reactive Graph

  • Declarative: You specify what to do, not when to do it.
  • Lazy: Code only runs when needed (when outputs are visible). When something upstream has changed we say that it invalidates.
  • Dependencies: Inputs \(\rightarrow\) Computations \(\rightarrow\) Outputs.
    • When an input changes, everything that depends on it invalidates.
    • Outputs re-calculate automatically.

Reactive Expressions

  • Problem: Duplicated code re-running multiple times.
  • Solution: reactive().
    • Splits logic into reusable chunks.
    • Cached (Lazy): Only re-runs if inputs change; otherwise returns saved value.
    • Called like a function: my_reactive().

Example

server <- function(input, output, session) {
  # Calculate once
  x_sq <- reactive({
    input$x ^ 2
  })
  
  # Use twice
  output$txt <- renderText(x_sq())
  output$plot <- renderPlot(plot(x_sq()))
}

Timing

  • You can use reactiveTimer to create time-based invalidation.
  • You can use eventReactive to create reactive expressions that only update in response to specific events (e.g., button clicks).

Observers

  • Outputs: Update the browser HTML.
  • Observers: Perform side effects (e.g., printing, saving, API calls).
    • Use observeEvent().
    • Triggered by an event (e.g., button click).
    • doesn’t return a value.
observeEvent(input$save, {
  write.csv(data(), "data.csv")
})

Reactive Graph

  • Let’s look at some examples in the text.

Summary

Mechanics

  • Server: function(input, output, session).
  • Input: Read-only, use in reactive context.
  • Output: Write-only (via render*).
  • Reactive Expressions: reactive({}) for calculations (cached).
  • Observers: observeEvent() for side effects.
  • Laziness: Nothing happens unless an output needs it.

Do Next

  1. Read Chapter 3: Reactivity from Mastering Shiny.
  2. There’s NO recitation Gem for this textbook but I recommend creating your own and adding the textbook chapter and these slides.
  3. I reommend working through the Exercises in the textbook.
  4. Move on to Lecture 21!