What's the difference between Reactive Value and Reactive Expression?
r, shiny
Solution
Using `currentFib <- reactiveValues({ fib(as.numeric(input$n)) })` will not work in this context. You will get an error saying that you are accessing reactive values outside of the "reactive context."
However, if you wrap it inside a function call instead, it will work:
`currentFib <- function(){ fib(as.numeric(input$n)) }`
This works because now the function call is inside a reactive context.
The key difference is the distinction they make in the Shiny documentation, between reactive "sources" and "conductors." In that terminology, `reactive({...})` is a conductor, but `reactiveValues` can only be a source.
Here's how I think of `reactiveValues` - as a way to extend `input` which gets specified in UI.R. Sometimes, the slots in `input` are not enough, and we want derived values based on those input slots. In other words, it is a way to extend the list of `input` slots for future reactive computations.
`Reactive()` does what you say -- it returns the value, after re-running the expression each time any reactive Value changes. If you look at the source code for `reactive` you can see it: The last line is that cached value that is being returned: `Observable$new(fun, label)$getValue` where 'fun' is the expression that was sent in the call to `reactive.`
Problem
In Shiny tutorial, there is an example: ``` fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2)) shinyServer(function(input, output) { currentFib <- reactive({ fib(as.numeric(input$n)) }) output$nthValue <- renderText({ currentFib() }) output$nthValueInv <- renderText({ 1 / currentFib() }) }) ``` I don't get how `reactive` caches the values. Does it internally do something like `return(function() cachedValue)`? Now I am wondering if I can do this? ``` fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2)) shinyServer(function(input, output) { currentFib <- reactiveValues({ fib(as.numeric(input$n)) }) output$nthValue <- renderText({ currentFib }) output$nthValueInv <- renderText({ 1 / currentFib }) }) ```