---
title: "Shiny Reactivity"
format: html
---

# Key Components of Shiny Reactivity:

## Reactive Inputs: 

These are user interface elements like sliders, text inputs, checkboxes, and dropdowns. When a user interacts with these elements, their values change, and Shiny recognizes these changes as triggers for reactivity.

## Reactive Expressions (`reactive()`, `eventReactive()`): 

These are R expressions that depend on reactive inputs or other reactive expressions. They are "lazy," meaning they only re-execute when their dependencies change and when their value is needed by an output or another reactive expression. 

- They are defined using the `reactive()` function and 
- Are called like functions (e.g., `my_reactive_expression()`).

## Reactive Outputs (`render*()` functions): 

These are the components displayed in the user's browser, such as plots, tables, or text. They are created using `renderPlot()`, `renderTable()`, `renderText()`, etc., and 

- Automatically re-render when their underlying reactive expressions or inputs change.

## Observers (`observeEvent()`, `observe()`): 

These are used for side effects, such as updating UI elements or writing to a database, that don't directly produce an output to be displayed. They execute whenever their dependencies change, similar to reactive expressions, 

- but their primary purpose is to trigger actions rather than return a value.

# Basic Reactivity

The `ui` is simple because every user gets the same HTML. The `server` is more complicated because every user needs to get an independent version of the app; when user A moves a slider, user B shouldn’t see their outputs change.  

To achieve this independence, Shiny invokes your server() function each time a new session5 starts. 

## Inputs are read-only

- Try to modify an input inside the server function, you’ll get an error:
- If you really want to `updateNumericInput()` is the way but we'll learn that later
- `input` is selective about who is allowed to read it. To read from an input, you must be in a reactive context created by a function like `renderText()` or `reactive()`. (Try accessing outside of these contexts and see what happens)

## Outputs

`output`, like `input` is a list-like object.  But `output` is always used in concert with a `render` function. 

The render function does two things:

- It sets up a special reactive context that automatically tracks what inputs the output uses.
- It converts the output of your R code into HTML suitable for display on a web page.

Like the input, the output is picky about how you use it. You’ll get an error if:

- You forget the render function.

```{r, eval = FALSE}
server <- function(input, output, session) {
  output$greeting <- "Hello human"
}
shinyApp(ui, server)
#> Error: Unexpected character object for output$greeting
#> ℹ Did you forget to use a render function?
```

- You attempt to read from an output.


```{r, eval = FALSE}
server <- function(input, output, session) {
  message("The greeting is ", output$greeting)
}
shinyApp(ui, server)
#> Error: Reading from shinyoutput object is not allowed.
```

## Reactive Programming

Run this example:

```{r, eval = FALSE}
ui <- fluidPage(
  textInput("name", "What's your name?"),
  textOutput("greeting")
)

server <- function(input, output, session) {
  output$greeting <- renderText({
    paste0("Hello ", input$name, "!")
  })
}
```

## Imperative vs declarative programming

This difference between commands and recipes is one of the key differences between two important styles of programming:

In imperative programming, you issue a specific command and it’s carried out immediately. This is the style of programming you’re used to in your analysis scripts: you command R to load your data, transform it, visualise it, and save the results to disk.

In declarative programming, you express higher-level goals or describe important constraints, and rely on someone else to decide how and/or when to translate that into action. This is the style of programming you use in Shiny.

With imperative code you say `Make me a sandwich`. With declarative code you say `Ensure there is a sandwich in the refrigerator whenever I look inside of it`. Imperative code is assertive; declarative code is passive-aggressive.

# More at

[mastering shiny](https://mastering-shiny.org/basic-reactivity.html#reactive-expressions-1)

