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

Shiny/R应用点击actionLink导致崩溃的问题求助

问题修复方案

问题根源

  1. 你把letter定义成了只读的reactive对象,但在observeEvent里直接用letter(.x)试图修改它——reactive对象只能通过依赖项自动更新,不能手动赋值,这是导致崩溃的直接原因。
  2. letters %>% map(...)会遍历所有26个字母,但大部分字母对应的input元素根本没在UI里生成,监听不存在的输入也会引发潜在错误。

修复后的完整代码

模块代码(无需修改)

library(shiny)
library(shinyWidgets)
library(tidyverse)

years <- 2015:2022

list_actions <- list(
  letters[1:3],
  letters[4:6],
  letters[7:9],
  letters[10:12],
  letters[13:15],
  letters[16:18],
  letters[19:21],
  letters[22:24]
)

list_actions <- list_actions %>% set_names(years)


module_UI <- function(id) {
  ns <- NS(id)
  tagList(
    uiOutput(ns('letter_1'))
  )
}

module_server <- function(id, app_control_input) {
  moduleServer(
    id,
    function(input, output, session) {
      output$letter_1 <- renderUI({
        h1(app_control_input())
      })
    }
  )
}

主应用代码(修改部分已标注)

ui <- fluidPage(
  radioGroupButtons(
    inputId = 'seasons',
    direction = 'horizontal',
    justified = 'TRUE',
    size = 'sm',
    label = '',
    choices = sort(years,decreasing = TRUE),
    selected = '2022'
  ),
  htmlOutput('actions_icons'),
  module_UI('overview')
)

server <- function(input, output, session) {

  # 1. 替换reactive为reactiveVal,支持手动更新值
  letter <- reactiveVal(list_actions[['2022']][1])

  # 2. 监听年份切换,自动更新为对应列表的第一个字母
  observeEvent(input$seasons, {
    letter(list_actions[[input$seasons]][1])
  })

  output$actions_icons <- renderUI({
    current_letters <- list_actions[[input$seasons]]
    current_letters %>%
      map(~ actionLink(label = .x, inputId = paste0('letter_', .x))) %>% # 给inputId加前缀,避免冲突
      tagList()
  })

  # 3. 动态监听当前年份生成的actionLink点击事件
  observeEvent(input$seasons, {
    current_letters <- list_actions[[input$seasons]]
    current_letters %>% map(function(l) {
      observeEvent(input[[paste0('letter_', l)]], {
        letter(l)
      })
    })
  }, ignoreInit = FALSE) # 初始化时就监听默认年份的字母

  module_server('overview', app_control_input = letter)

}

shinyApp(ui, server)

关键修改说明

  • 用reactiveVal替代reactive:reactiveVal是可读写的响应式变量,支持通过letter(new_value)手动更新值,符合点击字母修改显示内容的需求。
  • 动态监听有效输入:只对当前年份生成的字母添加observeEvent,避免监听不存在的输入元素,同时在年份切换时自动更新监听列表。
  • inputId加前缀:给actionLink的inputId加letter_前缀,避免和其他潜在的input元素重名,减少冲突风险。
  • 初始化监听:设置ignoreInit = FALSE,确保启动应用时默认年份的字母点击事件能被正确监听。

内容的提问来源于stack exchange,提问作者Laura

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:32:20