Skip to content

Opt-out of data-svelte-h #10992

Closed
Closed
@hyunbinseo

Description

@hyunbinseo

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 a data-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.

  1. Press Fail1 button. - Fail1 stays disabled.
  2. Press Fail2 button.
  3. 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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions