solid-router icon indicating copy to clipboard operation
solid-router copied to clipboard

useBeforeLeave event.defaultPrevented not updated

Open katywings opened this issue 9 months ago • 2 comments

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

https://github.com/solidjs/solid-router/blob/30f08665e87829736a9333d55863d27905f4a92d/src/lifecycle.ts#L23

katywings avatar May 14 '25 19:05 katywings

@Brendan-csel Do you by chance remember the reason for implementing the useBeforeLeave event in an immutable fashion 😁?

katywings avatar May 14 '25 19:05 katywings

I just needed something to work for my use-case - which only ever involved a single listener anyway.

Is there even a guarantee of the order listeners will be called? Or is it just a lucky side-effect of the current implementation and subject to change.

Brendan-csel avatar May 14 '25 20:05 Brendan-csel