fix: login button stuck on 준비 중 - Blazor hydration reverted JS enable
TaxBaik CI/CD / build-and-deploy (push) Successful in 2m24s
TaxBaik CI/CD / build-and-deploy (push) Successful in 2m24s
AdminLoginForm's submit button had disabled hardcoded as static markup, not bound to component state. The early inline <script> (before WASM boots) flipped it via raw DOM mutation, but when the WASM runtime later resumed the prerendered component, Blazor's own first render re-asserted the static disabled from the markup - silently undoing the JS fix. The second bindLoginForm() call from OnAfterRenderAsync then bailed out immediately on the one-shot "already bound" guard, so nothing ever re-enabled it. Fix: bind disabled to a real isReady field flipped in OnAfterRenderAsync so Blazor owns that attribute going forward, and make the JS-side enable idempotent (runs on every call, not gated behind the bind-once guard) as a second line of defense. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,10 +29,10 @@
|
||||
|
||||
<button type="submit"
|
||||
id="admin-login-submit"
|
||||
disabled
|
||||
disabled="@(!isReady)"
|
||||
class="mud-button-root mud-button mud-button-filled mud-button-filled-primary mud-elevation-0"
|
||||
style="width: 100%; min-height: 52px; border: 0; border-radius: 4px; color: white;">
|
||||
<span>준비 중...</span>
|
||||
<span>@(isReady ? "로그인" : "준비 중...")</span>
|
||||
</button>
|
||||
</form>
|
||||
</MudPaper>
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
@code {
|
||||
private string rememberedUsername = "";
|
||||
private bool isReady;
|
||||
private const string RememberedUsernameKey = "admin-remembered-username";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@@ -67,6 +68,15 @@
|
||||
{
|
||||
// Login UI must remain visible even if JS binding fails.
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Blazor owns this render from here on, so drive "disabled" from
|
||||
// C# state rather than a raw DOM mutation - otherwise this hydration
|
||||
// pass re-asserts the prerendered markup's static "disabled" and
|
||||
// silently undoes whatever the early inline <script> already set.
|
||||
isReady = true;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,13 +263,13 @@ window.taxbaikAdminSession = {
|
||||
|
||||
bindLoginForm: function () {
|
||||
const form = document.getElementById('admin-login-form');
|
||||
if (!form || form.dataset.bound === '1') return;
|
||||
if (!form) return;
|
||||
|
||||
form.dataset.bound = '1';
|
||||
window.taxbaikAdminSession.traceUiState('admin-login', 'bindLoginForm attached');
|
||||
|
||||
// 업데이트 스플래시: 제출 핸들러가 실제로 붙기 전까지는 버튼을 "준비 중" 상태로 두고,
|
||||
// 여기서 활성화해 사용자가 로그인 가능 시점을 알 수 있게 한다.
|
||||
// 업데이트 스플래시: 매번(재호출되어도) 무조건 다시 적용한다. Blazor가 WASM
|
||||
// 하이드레이션 시점에 이 prerender된 서브트리를 자신의 렌더 결과로 다시 그리면
|
||||
// 마크업에 정적으로 박혀 있던 disabled가 되살아날 수 있으므로, "한 번만 실행"
|
||||
// 가드에 걸어두면 두 번째 호출(OnAfterRenderAsync 경유)이 조용히 무시되어
|
||||
// 버튼이 영원히 비활성 상태로 남는다. 그래서 이 부분은 가드 밖에 둔다.
|
||||
const readyButton = form.querySelector('#admin-login-submit');
|
||||
if (readyButton) {
|
||||
readyButton.disabled = false;
|
||||
@@ -277,6 +277,10 @@ window.taxbaikAdminSession = {
|
||||
if (label) label.textContent = '로그인';
|
||||
}
|
||||
|
||||
if (form.dataset.bound === '1') return;
|
||||
form.dataset.bound = '1';
|
||||
window.taxbaikAdminSession.traceUiState('admin-login', 'bindLoginForm attached');
|
||||
|
||||
form.addEventListener('submit', async function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user