From 9e5bf42802d4a556bb56c1ee68e27706b4060a15 Mon Sep 17 00:00:00 2001
From: huyan
Date: Thu, 6 Aug 2026 17:27:09 +0800
Subject: [PATCH 06/15] fix(project-create): latch repeat submits on a ref
The submit handler read the submitting flag out of its own render closure, so within one batch of events the second submit still saw the stale value and only the disabled attribute stopped it.
Hold the in-flight state in a ref and check that before doing any work, releasing it when the request fails.
The guard the handler claims to have is the one that actually runs.
---
frontend/src/pages/project-create/index.tsx | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/frontend/src/pages/project-create/index.tsx b/frontend/src/pages/project-create/index.tsx
index 89d3a1a8..db49d9e2 100644
--- a/frontend/src/pages/project-create/index.tsx
+++ b/frontend/src/pages/project-create/index.tsx
@@ -1,4 +1,4 @@
-import { useState, type FormEvent } from 'react'
+import { useRef, useState, type FormEvent } from 'react'
import { useNavigate } from 'react-router'
import {
@@ -39,10 +39,12 @@ export function ProjectCreatePage() {
const [gameStyle, setGameStyle] = useState('')
const [submitting, setSubmitting] = useState(false)
const [error, setError] = useState(null)
+ /** 同一批事件里 submitting 还是上一次 render 的值,按钮变灰之前的重复提交只能靠这个挡。 */
+ const inFlight = useRef(false)
async function submit(event: FormEvent) {
event.preventDefault()
- if (submitting || !ownerId) return
+ if (inFlight.current || !ownerId) return
const trimmedName = name.trim()
const width = Number(spriteWidth)
@@ -54,6 +56,7 @@ export function ProjectCreatePage() {
return setError(`精灵宽高需要是 ${SPRITE_MIN} 到 ${SPRITE_MAX} 之间的整数`)
}
+ inFlight.current = true
setSubmitting(true)
setError(null)
try {
@@ -71,6 +74,7 @@ export function ProjectCreatePage() {
setError(
cause instanceof ApiError && cause.kind === 'business' ? cause.message : '项目暂时无法创建',
)
+ inFlight.current = false
setSubmitting(false)
}
}
From daa025dab169b775db2e98e5b40b5dc35292e8d2 Mon Sep 17 00:00:00 2001
From: huyan
Date: Thu, 6 Aug 2026 17:27:24 +0800
Subject: [PATCH 07/15] fix(project-create): drop the stale error when a field
changes
The error banner stayed on screen while the user corrected the field it complained about, so the page kept accusing them of something they had already fixed.
Clear it from a single change handler on the form, which every control inside already bubbles to.
The banner describes the current state of the form rather than the last attempt.
---
frontend/src/pages/project-create/index.tsx | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/frontend/src/pages/project-create/index.tsx b/frontend/src/pages/project-create/index.tsx
index db49d9e2..37b45d7d 100644
--- a/frontend/src/pages/project-create/index.tsx
+++ b/frontend/src/pages/project-create/index.tsx
@@ -90,7 +90,12 @@ export function ProjectCreatePage() {
{/* pt-24 与 PageContainer 同源:给 fixed 顶栏(top-3.5 加最小高 3.625rem)让位,改顶栏尺寸时一起改。 */}