How to call `useNavigate` outside of router
I am trying to create my own "page viewer" where I will be able to navigate between pages within the site;
Currently I am using the Solid Router. But I want to be able to call the "window" to navigate from outside of the router. But I can't do that.
I get the following error when trying to call
useNavigate
I want to be able to do the following outside of the router:
1. Go back
2. Go forwards
3. Reload
4. Navigate
5. Clear navigation history
So far I know for going forwards and backwards I can use history.back
. But I cant refresh using location.reload
because the window is a dialog so reloading is going to close the dialog. And the other options I don't really know what I can do.
I tried to get the Navigate
function by using the Navigate
component and then taking the function from the parameter passed in the href
e.g.
But that still causes errors and is ugly code. Any suggestions on what I can do? Thanks32 Replies
Any specific reason why you want it outside the router? Most code i have seen has the router at the root.
The router isnt at the root because my "site" is being run with tauri.
So because it is a desktop app, I dont want to navigate the whole page. Just a section of it.
If this was my problem I'd look into crafting a
Router
root
component that subscribes to a NavigationSubject that code outside of Router
can dispatch navigation events to.How would I do the subscribing and observing?? Did some research and think I can use
createContext
but I am not too sure.Something a lot more basic than that, your own vanilla JavaScript module. Here's an example that I used:
https://github.com/peerreynders/nitro-sse-counter/blob/6f27d5d7bd9e119ca2fc1feb7cbe70f9308b84b6/src/client/lib/sinks.js
When you create a
Sinks<T>
instance you can hand around it's send
property (i.e. it's not method) to anyone who wants to dispatch T
values, while you can pass around the add
property, so that anyone can be notified of those values.
So the root
component would add
itself listening for navigation events send
(sent) from the outside.
TC39:
“There is an interest in an Observable
but no one wants to deal with which one”
So everybody keeps creating their own …GitHub
nitro-sse-counter/src/client/lib/sinks.js at 6f27d5d7bd9e119ca2fc1f...
SSE POC with UnJS Nitro and a TS JSDoc frontend. Contribute to peerreynders/nitro-sse-counter development by creating an account on GitHub.
GitHub
notes/meetings/2017-05/may-25.md at 57e6c4ef05d868129733ce31f200d68...
TC39 meeting notes. Contribute to tc39/notes development by creating an account on GitHub.
Hmm. This seems a bit complex for me right now...
Thanks though. The whole process of observing is what I don't understand I think.
may i ask why running in tauri impacts whether the router is at the root? making your whole app be controlled by the one router seems like it'd be easier
Yeh. I could have it be multiple pages where I do navigation. But the design of my app is that there is a
page-viewer
which would load different pages. And it will have its own navigation. Then I would be able to close the viewer to access the homescreen.
It is a bit complicated but that is what I thought would be cool to make i guess.
I could just make my own router sort of. Just don't know how to "attach" methods to a component to call stuff for it. (Just a way I could be doing the routing)At a first glance I'd implement that with
/home
and /page/{page id}
routes
And then under /page/{page id}
you can have all the page viewer's routesThat is still involving multiple pages right?
Here is my current layout
i assume each page has its own id, you'd just swap out the page id in the url and be viewing a different page
Oh interesting so it's more of a modal view than a dedicated route?
Yeh. But wouldn't that mean for each page I need to recreate the sidebar and stuff
Yeh it is
Nah the sidebar and things would live in a layout that exists at
/page
yeah this makes things a bit more interestingAnd
/home
i guess too.yeah in that case the layout can be at
/
ok... I still don't want to create multiple paths. Because at the home screen is a bunch of data that is taken from a config file. And I don't want to reload that information.
if u fetch the data in a shared layout and the layout doesn't unmount then the information doesn't have to reload
but the modal-ness of this makes it interesting
i'm guessing the base view contains all the pages and then clicking on one opens the page viewer modal?
Yeh. And the sidebar directs to pages as well. And... some pages navigate to other pages lol
but the modal always appears on top of the existing route rather than completely replacing it yeah?
yeah
I am using a dialog to open and close it
yeah that's a really intricate design, i think for that i'd store the dialog state in search params and roll my own mini router since it just doesn't fit with normal route nesting
Yeh a "mini router" that is what I was thinking to make
a json object in search params and some switch/match cases would do the trick
why in the search params?
I could store it as a global variable right...?
yeah u could, but search params are also global variables...
i just like keeping stuff in the url where possible
web dev mentality
Yeh that makes sense. And if it were a website that is how I would do it as well. But considering that this is a site with no url bar then it shouldnt be needed
actually even for tauri apps counting on url state can be pretty useful for if u need to restore a user's session - just swap out the url
once you've got state outside the url you need extra ways of persisting and loading it
True. I don't want the state to be saved if the app just launches. But definatly when I restore the window after it came from the tray
But im not sure if tauri saves the window state if it goes to the tray
Electron does I think... so idk
I might try creating a mini router component with data from a global signal
Ok @Brendonovich, I have made it. Havent tested navigation yet. But have something... might not be the best way to do it though.
Then to use it I did the following
Sorry bit long. If you want it somewhere else I can do that
Made a couple modifications. Now it navigates...
Updated the code with the modifications
Here is the solidjs playground for it: https://playground.solidjs.com/anonymous/097424a8-e664-4785-95f0-456fff6aad3a
Note: There is a bug because I can't export solids JSX.Element type in the playground
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Here is an example: https://stackblitz.com/edit/stackblitz-starters-n8eugp?file=src%2Fapp.tsx
peerreynders
StackBlitz
solid-router external navigation - StackBlitz
external.ts holds a link object that flipper.ts sends NavigationEvents to which are forwarded to the root component in app.tsx
Thanks might take a look at it later. I got something to work for now though (code above ^^)