R Shiny中响应式链路内对象隐藏时如何维持链路正常运行?
问题原因
Shiny 默认会暂停隐藏状态下的输出对象渲染逻辑,用来减少不必要的性能开销。你代码里的 output$secondInput 初始用 hidden() 包裹,只要没触发过显示,或者显示后重新隐藏,修改第一个矩阵时第二个矩阵的UI不会触发更新,对应的 input$input2 值无法同步,最终导致绘图的响应式链路断裂。
最简实现方案
只需要在服务端增加一行配置,关闭 secondInput 输出的「隐藏时暂停渲染」规则即可,无需修改其他现有逻辑:
outputOptions(output, "secondInput", suspendWhenHidden = FALSE)
修改后完整可运行代码
rm(list = ls()) library(shiny) library(shinyMatrix) library(shinyjs) firstInput <- function(inputId){ matrixInput(inputId, value = matrix(c(5), 1, 1, dimnames = list(c("1st input"),NULL)), rows = list(extend = FALSE, names = TRUE), cols = list(extend = FALSE, names = FALSE, editableNames = FALSE), class = "numeric")} secondInput <- function(inputId,x){ matrixInput(inputId, value = matrix(c(x), 1, 1, dimnames = list(c("2nd input"),NULL)), rows = list(extend = FALSE, names = TRUE), cols = list(extend = FALSE, names = FALSE, editableNames = FALSE), class = "numeric")} ui <- fluidPage( titlePanel("Model"), sidebarLayout( sidebarPanel( uiOutput("panel"), hidden(uiOutput("secondInput")) ), mainPanel(plotOutput("plot1")) ) ) server <- function(input, output) { # 新增:关闭隐藏时暂停渲染的规则 outputOptions(output, "secondInput", suspendWhenHidden = FALSE) input1 <- reactive(input$input1) input2 <- reactive(input$input2) output$panel <- renderUI({ tagList( useShinyjs(), firstInput("input1"), actionButton('show','Show 2nd inputs'), actionButton('hide','Hide 2nd inputs')) }) output$secondInput <- renderUI({ req(input1()) secondInput("input2",input$input1[1,1]) }) output$plot1 <-renderPlot({ req(input2()) plot(rep(input2(),times=5)) }) observeEvent(input$show,{shinyjs::show("secondInput")}) observeEvent(input$hide,{shinyjs::hide("secondInput")}) } shinyApp(ui, server)
备选拓展方案
如果后续逻辑更复杂,也可以用响应式变量做中间存储层,完全不依赖第二个矩阵的UI渲染状态:
- 定义一个
reactiveVal存储第二个输入的有效值 - 第一个矩阵修改时,如果用户没有手动改第二个矩阵的值,就自动同步第一个矩阵的值到中间变量
- 用户手动修改第二个矩阵时,优先用用户输入的值
- 绘图直接读取中间变量即可,不需要依赖
input$input2的存在
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

