Can I save the old value of a reactive object when it changes?

后端 未结 2 2145
不思量自难忘°
不思量自难忘° 2021-02-13 04:56

Note: After coming up with the answer I reworded the question to make if clearer.

Sometimes in a shiny app. I want to make use of a value s

2条回答
  •  死守一世寂寞
    2021-02-13 05:27

    Update This answer was posted before the advent of the reactiveValues/observeEvent model in shiny. I think that @MikeWise 's answer is the better way to do this.

    After some playing around this is what I came up with. The ui.r is nothing special

    ui.r

    library(shiny)
    
    ui <- shinyUI(fluidPage(
      sidebarLayout(
        sidebarPanel(
          selectizeInput(inputId="XX", label="Choose a letter",choices=letters[1:5])
        ),
        mainPanel(
          textOutput("Current"),
          textOutput("old")
        )
      ) 
    ))  
    

    "Current" will display the current selection and "old" displays the previous selection.

    In the server.r I made use of three key functions: reactiveValues, isolate and session$onFlush.

    server.r

    library(shiny)
    
    server <- function(input, output,session) {
    
      Values<-reactiveValues(old="Start")
    
      session$onFlush(once=FALSE, function(){
        isolate({ Values$old<-input$XX })
      })
    
    
      output$Current <- renderText({paste("Current:",input$XX)})
    
      output$old <- renderText({ paste("Old:",Values$old) })
    }  
    

    The server.r works like this.

    First, Values$old is created using the reactiveValues function. I gave it the value "Start" to make it clear what was happening on load up.

    Then I added a session$onFlush function. Note that I have session as an argument in my server function. This will run every time that shiny flushes the reactive system - such as when the selectizeInput is changed by the user. What is important is that it will run before input$XX gets a new value - so the value has changed at the selectizeInput but not at XX.

    Inside the session$onFlush I then assign the outgoing value of XX to Values$old. This is done inside an isolate() as this will prevent any problems with input$XX gets updated with the new values. I can then use input$XX and Values$old in the renderText() functions.

提交回复
热议问题