我遇到了一种情况,当它调用renderUI小部件中的某些输入时会多次评估反应式表达式。
请检查以下简单代码。
library(shiny)
server <- function(input, output) {
output$INPUT_1 = renderUI({
selectInput("input_1","Input 1",choices = letters)
})
output$INPUT_2 = renderUI({
selectInput("input_2","Input 2",choices = letters)
})
output$INPUT_3 = renderUI({
selectInput("input_3","Input 3",choices = letters)
})
output$INPUT_4 = renderUI({
selectInput("input_4","Input 4",choices = letters)
})
output$text = renderText({
print("1")
paste(input$input_1,input$input_2,input$input_3,input$input_4)
})
}
ui <- fluidPage(
uiOutput("INPUT_1"),
uiOutput("INPUT_2"),
uiOutput("INPUT_3"),
uiOutput("INPUT_4"),
textOutput("text")
)
shinyApp(ui = ui, server = server)
如果你看看你的控制台,你会看到
Listening on http://127.0.0.1:4939
[1] "1"
[1] "1"
“1”来了两次。
我自己的应用程序的“1”超过3次。由于我的每一个被动处理大数据,这种情况真的让我的用户和我自己感到尴尬。
我几乎可以肯定这与renderUI工具有关。但我仍然无法找到解决问题的方法。我考虑使用updateXXXXX功能,但我的输入UI包含非常复杂的计算。所以使用updateXXXXX是我想要避免的。
我的反应性表达怎么只能评估一次?
答案 0 :(得分:2)
Shiny带有一个名为req
的额外函数,可帮助您控制观察者的执行,即使某些控制元素在某些服务器端调用中即时呈现。
有关完整文档,请参阅this page here。简而言之,您可以在反应环境中列出一组输入变量(观察者,反应值或渲染函数),并且在所有输入变量都分配了值之前,不会计算/执行此反应环境。
在您的情况下,您只需添加行
即可req(input$input_1, input$input_2,input$input_3, input$input_4)
给你的观察者,它只会被执行一次。 (由于 Arcoutte 对你的帖子的评论中所述的原因,它被执行了两次。)
完整的示例代码。
library(shiny)
server <- function(input, output) {
output$INPUT_1 = renderUI({
selectInput("input_1","Input 1",choices = letters)
})
output$INPUT_2 = renderUI({
selectInput("input_2","Input 2",choices = letters)
})
output$INPUT_3 = renderUI({
selectInput("input_3","Input 3",choices = letters)
})
output$INPUT_4 = renderUI({
selectInput("input_4","Input 4",choices = letters)
})
output$text = renderText({
req(input$input_1,input$input_2,input$input_3,input$input_4)
print("1")
paste(input$input_1,input$input_2,input$input_3,input$input_4)
})
}
ui <- fluidPage(
uiOutput("INPUT_1"),
uiOutput("INPUT_2"),
uiOutput("INPUT_3"),
uiOutput("INPUT_4"),
textOutput("text")
)
shinyApp(ui = ui, server = server)