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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions