Closed
Description
Describe the bug
In the following example, even if the form's default action returns { date: new Date() }
formArray
is updated and therefore logged in the console.<button>
element is not recreated, since it has adata-svelte-h
attribute.<button>
element stays disabled.
<script lang="ts">
import { enhance } from '$app/forms';
export let form;
$: formArray = [form];
$: console.log(formArray);
</script>
<form
method="post"
use:enhance
on:submit={(e) => {
if (e.submitter instanceof HTMLButtonElement) e.submitter.disabled = true;
}}
>
{#if !form || form.date}
{#each formArray as _}
<button>Button</button>
{/each}
{/if}
</form>
Improve hydration speed by adding
data-svelte-h
attribute to detect unchanged HTML elements (sveltejs/svelte#7426)
Reproduction
Reference the StackBlitz project.
The reproduction's goal is to disable the submit button until the form action responds, thus blocking double submit.
- Press Fail1 button. - Fail1 stays disabled.
- Press Fail2 button.
- Press Fail3 button. - Fail3 button is recreated and can be pressed.
// +page.server.ts
import { fail } from '@sveltejs/kit';
export const actions = {
message: () => fail(400, { message: 'Hello World' }),
date: () => fail(400, { date: new Date() }),
};
<!-- +page.svelte -->
<script lang="ts">
import { enhance } from '$app/forms';
import type { Action } from 'svelte/action';
export let form;
const action: Action = (node) => {
if (node instanceof HTMLButtonElement) {
console.log(`${node.textContent} button is mounted.`);
console.log(node);
}
};
$: formArray = [form];
$: console.log(formArray);
</script>
<form
method="post"
use:enhance
on:submit={(e) => {
if (e.submitter instanceof HTMLButtonElement) {
console.log(`${e.submitter.textContent} button is disabled.`);
e.submitter.disabled = true;
}
}}
>
{#if !form || form.date}
{#each formArray as _}
<button use:action formaction="?/date">Fail1</button>
{/each}
<button use:action formaction="?/message">Fail2</button>
{:else}
{#if form}
<button use:action formaction="?/message">Fail3</button>
{/if}
{/if}
</form>
Logs
Array [ null ]
Fail1 button is mounted.
<button formaction="?/date" data-svelte-h="svelte-1nb5vgx">
Fail2 button is mounted.
<button formaction="?/message" data-svelte-h="svelte-j1ksp3">
### Press Fail1 button #####################################
Fail1 button is disabled.
Array [ {…} ]
### Press Fail2 button #####################################
Fail2 button is disabled.
Array [ null ]
Array [ {…} ]
Fail3 button is mounted.
<button formaction="?/message">
### Press Fail3 button #####################################
Fail3 button is disabled.
Array [ null ]
Fail1 button is mounted.
<button formaction="?/date">
Fail2 button is mounted.
<button formaction="?/message">
Array [ {…} ]
Fail3 button is mounted.
<button formaction="?/message">
System Info
Binaries:
Node: 18.18.0 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 9.4.2 - /usr/local/bin/npm
pnpm: 8.9.2 - /usr/local/bin/pnpm
npmPackages:
@sveltejs/adapter-auto: ^2.1.0 => 2.1.1
@sveltejs/kit: ^1.27.2 => 1.27.3
svelte: ^4.2.2 => 4.2.2
vite: ^4.5.0 => 4.5.0
Severity
annoyance
Additional Information
- I would love to manually disable
data-svelte-h
attributes. {#if form}
seems to be enough to recreate Fail3 button.
Metadata
Metadata
Assignees
Labels
No labels