Skip to content

useBeforeLeave event.defaultPrevented not updated #530

@katywings

Description

@katywings

Describe the bug

When you use useBeforeLeave multiple times, each listener receives a copy of the event, therefore an early listener cannot know if a later listener did call preventDefault.

Reproduction:

useBeforeLeave(evt => requestAnimationFrame(() => console.log(evt.defaultPrevented)));
useBeforeLeave(evt => evt.preventDefault());
// Logs: false

Your Example Website or App

Reproduction code in description

Steps to Reproduce the Bug or Issue

  1. Create a solid start project
  2. Add the reproduction code from above to the App component
  3. Open the project in the browser
  4. Click on a Solid-Router powered link
  5. Check the browser console

Expected behavior

You should be able to read the up-to-date value of defaultPrevented. The above reproduction should log true.

Screenshots or Videos

No response

Platform

  • OS: Linux
  • Browser: Zen
  • Version: 1.12.3b (Firefox 138.0.1)

Workaround

This lets you attach a listener early, yet read the defaultPrevented late:

import { useBeforeLeave } from "@solidjs/router";
import { createRoot } from "solid-js";

export const useBeforeLeaveLate = (
  listener: Parameters<typeof useBeforeLeave>[0],
) =>
  useBeforeLeave(() =>
    createRoot((dispose) =>
      useBeforeLeave((e) => {
        dispose();
        listener(e);
      }),
    ),
  );

Reason

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions