如何在Shiny App中根据textInput和指定条件渲染及移除UI元素
问题原因
- 核心问题出在
removeUI的使用逻辑:你调用removeUI(selector = "#new")的时候,会直接从DOM结构中删除id为new的节点,而这个节点就是你提前定义的uiOutput("new")。一旦被删除后,后续就算满足渲染条件,renderUI生成的内容也没有对应的挂载节点,自然无法显示。 - 次要逻辑冗余:你已经在
res响应式变量里做了匹配过滤,不需要额外拼接字符串再做正则匹配,直接判断res()的返回长度是否大于0即可判断是否有匹配结果。
修正方案
不需要手动调用removeUI,直接在renderUI里加条件判断,不满足条件的时候返回NULL就会自动隐藏内容,同时保留DOM里的uiOutput节点方便后续渲染。
library(shiny) library(tidyverse) data = starwars ui = fluidPage( textInput("txt", "Look up name"), uiOutput(outputId = "new") ) server = function(input, output, session){ res = reactive({ req(input$txt) data %>% filter(str_detect(name, fixed(input$txt))) %>% slice_min(order_by = birth_year, n = 3) %>% pull(name) }) output$new <- renderUI({ if(nchar(input$txt) > 2 && length(res()) > 0){ map(.x = res(), .f = ~div(.x)) }else{ NULL } }) } shinyApp(ui, server)
可选优化点
- 用
fixed(input$txt)包裹匹配字符串,避免用户输入特殊正则字符导致匹配出错 - 用
req(input$txt)避免响应式变量在输入为空时报不必要的警告 - 不需要给renderUI里的div重复设置id为new,避免和外层uiOutput的id冲突
内容的提问来源于stack exchange,提问作者werN
相关产品推荐
相关产品推荐

