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

Shiny注册按钮重置问题:避免未点击时触发通知与操作

Fix Shiny Register Button Triggering Unintentionally

Got it, let's fix this issue step by step. The core problem with your original code is using observe() instead of a button-specific reactive handler—observe() will re-run whenever any of its dependent reactive values change (like input fields, the button's click count, or USER$registed), which is why you're seeing unintended triggers after the first successful registration.

Here's the corrected approach:

Key Fixes

  • Use observeEvent() to only run code when the regist button is clicked (this eliminates accidental triggers from other input changes).
  • Add req() to ensure the code only executes when the user is in registration mode (USER$registed == TRUE).
  • Replace unsafe sprintf() SQL queries with parameterized queries to avoid SQL injection (critical for security).
  • Remove redundant checks for input$regist > 0—observeEvent() already handles this by default.

Corrected Code

observeEvent(input$regist, {
  # Only run if user is in registration mode
  req(USER$registed == TRUE)
  
  # Check for empty inputs
  if (is.null(input$uname) || input$uname == "" || 
      is.null(input$pswd) || input$pswd == "" || 
      is.null(input$email) || input$email == "") {
    showNotification("You Forgot to insert your information!", 
                     duration = 3, type = "error")
    return() # Exit early if inputs are missing
  }
  
  # Isolate inputs to avoid unnecessary reactivity
  Username <- isolate(input$uname)
  Password <- isolate(input$pswd)
  Email <- isolate(input$email)
  
  # Connect to database
  db <- dbConnect(SQLite(), dbname="db.sqlite")
  on.exit(dbDisconnect(db)) # Ensure connection closes even if errors occur
  
  # Check for existing user/email (parameterized query for safety)
  existed <- dbGetQuery(
    db, 
    "SELECT rowid FROM users WHERE username = ? OR password = ? OR email = ?",
    params = list(Username, Password, Email)
  )
  
  if (nrow(existed) >= 1) {
    showNotification(
      "This Username, Password or Email already exist in the system. Please try something else!",
      duration = 4, type = "error"
    )
  } else {
    # Insert new user (parameterized queries)
    dbExecute(
      db, 
      "INSERT INTO users (username,password,email) VALUES (?, ?, ?)",
      params = list(Username, Password, Email)
    )
    
    # Get and assign new student ID
    MAX_studentID <- dbGetQuery(db, "SELECT MAX(studentID) FROM UserID_Map")[[1]]
    New_user_StudentID <- as.integer(MAX_studentID) + 1
    
    dbExecute(
      db, 
      "INSERT INTO UserID_Map (username,studentID) VALUES (?, ?)",
      params = list(Username, New_user_StudentID)
    )
    
    showNotification(
      "Successful Registeration. You can Login!",
      duration = 4, type = "message"
    )
  }
})

Why This Works

  1. observeEvent(input$regist, ...): This handler only activates when the regist button is explicitly clicked. It won't run if you edit input fields or change other reactive values after the first click.
  2. req(USER$registed == TRUE): Ensures the code only runs when the user is actually on the registration screen (prevents accidental execution if USER$registed is FALSE later).
  3. Parameterized Queries: Using ? placeholders and params list avoids SQL injection attacks—never use sprintf() to build SQL queries with user input!
  4. on.exit(dbDisconnect(db)): Guarantees the database connection closes even if an error occurs during execution (prevents leftover open connections).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:44:39