如何理解shiny中的reactivity?

官方文档

https://shiny.rstudio.com/articles/understanding-reactivity.html

理解

1. reactive 和 eventReactive

reactive 是模块化反应机制,如下代码中fib(as.numeric(input$n))被单独执行了两次,浪费资源。

fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))

server <- function(input, output) {
  output$nthValue    <- renderText({ fib(as.numeric(input$n)) })
  output$nthValueInv <- renderText({ 1 / fib(as.numeric(input$n)) })
}

我们使用reactive可以生成一个中间表达式,暂存结果在currentFib,后面调用currentFib省去计算过程。

fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))

server <- function(input, output) {
  currentFib         <- reactive({ fib(as.numeric(input$n)) })

  output$nthValue    <- renderText({ currentFib() })
  output$nthValueInv <- renderText({ 1 / currentFib() })
}

reactive会时刻监视 input 的每一个改变做出响应,但是有时候我们并不希望如此。例如运用多个条件对数据进行筛选的时候,我们可能是一个一个条件输入的,并不希望每改变一个条件就输出一个表格或者图片,这样会很浪费计算资源。这个时候希望更改完所有条件后,一起提交输入,进行计算,需要用到eventReactive

## 这个例子在拖动控件的时候,输出的表格会随着变化
library("shiny")
shinyApp(
  ui = fluidPage(
    column(4,
           sliderInput("x", "Value",
                       min = 1, max = 10,
                       value = 3),
           actionButton("button", "Show")
    ),
    column(8, tableOutput("table"))
  ),
  server = function(input, output) {
    df <-reactive({
      head(cars, input$x)
    })
    output$table <- renderTable({
      df()
    })
  }
)
## 这个滑动控件后,只有监视到按钮事件,输出才发生改变
shinyApp(
  ui = fluidPage(
    column(4,
           sliderInput("x", "Value",
                       min = 1, max = 10,
                       value = 3),
           br(),
           actionButton("button", "Show")
    ),
    column(8, tableOutput("table"))
  ),
  server = function(input, output) {
   df <- eventReactive(input$button, {
      head(cars, input$x)
    })
    output$table <- renderTable({
      df()
    })
  }
)

2. observe 和 observeEvent

observereactive 相同点都是能响应 input 的变化,不同点是 observer 没有返回值,不能向下传递,所以就不能作为 render 的输入。顾名思义,它只是起监视作用。下面例子,当滑动使 x > 5时,界面发送通知。

shinyApp(
  ui = fluidPage(
    sliderInput("x", "Value",
                min = 1, max = 10,
                value = 3)
  ),
  server = function(input, output) {
    observe({
      if(input$x > 5)
      showNotification("value > 5")
    })
  }
)


相同的 observeEvent 只是再增加一个监视条件,起延时作用。例如下面例子,滑动滑杆时,并不去判断 x > 5,只有按下按钮,才执行下面的代码。

shinyApp(
  ui = fluidPage(
    sliderInput("x", "Value",
                min = 1, max = 10,
                value = 3),
    actionButton("go", "Go")
  ),
  server = function(input, output) {
    observeEvent(input$go,{
      if(input$x > 5)
      showNotification("value > 5")
    })
  }
)
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容