You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:40:38