如何确保Shiny中reactable::getReactableState()在表格重绘时返回正确行选中状态?
问题:切换数据集时Reactable表格选中状态未及时重置
我开发了一个包含父reactable表格和钻取表格的Shiny应用,点击父表格行可弹出钻取表格,通过reactable::getReactableState()获取父表格选中行信息。但切换数据集生成新父表格时,该函数返回旧表格的行选中状态,而非更新后的表格状态。
即便新父表格已完成渲染,钻取表格计算时仍会使用旧选中状态,直到应用空闲后,reactable::getReactableState()的输入才会失效,响应式对象重新运行,此时才会返回正确的无选中行结果。
参考响应式图,我希望每次input$tables-data_set变化时,将input$tables-table_parent__reactable__selected设为NULL。

我尝试使用session$sendCustomMessage()和Shiny.addCustomMessageHandler方法修改输入值,但修改后的信息需在所有输出计算完成后才会传递到浏览器,无法及时生效。
最小可复现代码
UI模块
drilldownUI <- function(id) { ns <- NS(id) tagList( tags$script(" Shiny.addCustomMessageHandler('tables-table_parent__reactable__selected', function(value) { Shiny.setInputValue('tables-table_parent__reactable__selected', value); }); "), shiny::selectizeInput( inputId = ns("data_set"), label = "Data set", choices = c("iris", "cars"), selected = "iris" ), reactable::reactableOutput(outputId = ns("table_parent"), width = "100%"), reactable::reactableOutput( outputId = NS(id, "drilldown_table"), width = "100%" ) ) }
Server模块
drilldownServer <- function(id, dat) { moduleServer(id, function(input, output, session) { dataset <- reactive({ data_list <- list(iris = as.data.table(iris), cars = as.data.table(MASS::Cars93)) data_list[[input$data_set]] }) data_grouped <- reactive({ dataset()[, .N, by = c(grouping_var())] }) grouping_var <- reactive({ if (input$data_set == "iris") { return("Species") } "Origin" }) output$table_parent <- reactable::renderReactable({ req(input$data_set) reactable::reactable( data_grouped(), selection = "single", onClick = "select" ) }) selected <- reactive({ out <- reactable::getReactableState("table_parent", "selected") if(is.null(out)||out=="NULL") return(NULL) out }) output$drilldown_table <- reactable::renderReactable({ req(selected()) # 这段代码应该在新父表格生成且选中状态重置为NULL后才触发,但实际是新表格生成后、选中状态重置前就触发了 selected_group <- data_grouped()[selected(), ][[grouping_var()]] drilldown_data <- dataset()[get(grouping_var()) == selected_group] reactable::reactable(drilldown_data) }) observeEvent(input$data_set, { session$sendCustomMessage("tables-table_parent__reactable__selected", 'NULL') }) }) }
应用入口
library(shiny) library(reactable) library(data.table) # 定义应用UI ui <- fluidPage( drilldownUI("tables") ) # 定义应用server逻辑 server <- function(input, output) { drilldownServer("tables") } # 运行应用 shinyApp(ui = ui, server = server)
内容的提问来源于stack exchange,提问作者rove
相关产品推荐
相关产品推荐

