invoke navigate() after function call but before signal update propagates to ui
i have this function
in this case, the joinGroup function will result in a signal update, which then results in a ui update
i want the user to navigates away before the ui update, otherwise they see a flash of a view for their new state before the nav happens. this is fine but not great ux. i've tried wrapping this in a startTransition, but i don't see much happening
one option is to navigate before the joinGroup call. this is fine because joingroup is very fast, but it feels wrong to send the user off before the operation to actually grant them access there is begun. does anyone have thoughts?
22 Replies
does setTimeout work?
it could, but i was hoping there was a more native way to handle somethign like this
:Worry_Think:
well actually setTimeout wouldn't work
that wouldn't really do much for me i don't think
So the goal is to update without triggering the UI update?
:Worry_Think:
the goal is to invoke joinGroup and navigate before the next render, so basically, yea
by the time joinGroup finishes, the ui will have gotten the signal updates
and as such, navigate comes in too late
i can't put navigate before joinGroup with any sort of confidence, because then i may send the user to their next page before the app state is totally updated
Is joinGroup a promise?
Yea
But it resolves very fast
There is the option to just track with a signal if the user clicked the submit button, and if so, force the page to keep the original view. But I feel like there’s a got to be a better solution
It resolves very fast but you could just use the
.then
part of it to navigate after it's done just in casethis should not matter. transition batches along sync (signal) => async (resources)
Yea even in the .then it’s already updated in the ui
Maybe the issue is that the navigation isn’t instant?
is there some
await
-ing before navigate
gets called?
synchronous updates must still happen in the same task
at least until async context lands in browserno
joinGroup returns a void promise, which i don't await, and then navigate is called next, nothing in between
the signal that updates as a result of joinGroup is a memo
Maybe you can make use of onBeforeLeave?
Oops sorry it's useBeforeLeave*
https://github.com/solidjs/solid-router?tab=readme-ov-file#usebeforeleave
same problem
.
which means,
navigate
gets called first
the fact that it's an async function suggests that there's some updates across microtasks
better if you could reproduce it in the playgroundmight be tough in playground, working on a repro rn though
not necessarily have to be playground, stackblitz, csb, etc
yea there's something weird on my end going on. the minimal-ish repro i could make it only happens if i wrap the navigate in a setTimeout
in that the nav happens before the next frame, so i'm not sure i'll have to look into my code a little more
here's my whole component, maybe i'm messing up the conditional rendering in some way?
Just some observations:
What I'm not seeing is
1. a Suspense boundary
2. whether or not
joinGroup
does anything that would trigger a Suspense boundary
With a Suspense boundary in place a transition should start()
paint- holding, performing the next render in the background.
With something like
I would expect the navigation to start before the nearest suspense boundary has a chance to swap in the updated render.Chrome for Developers
Paint Holding - reducing the flash of white on same-origin navigati...
A quick overview of paint holding. A Chrome feature for reducing the flash of white on same-origin navigations
There's no suspense boundary, but none of the signals i'm accessing are async (ie. createResource/createAsync)
or at least as far as I can tell