You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Router: Easier access to route() in class components #930
Is your feature request related to a problem? Please describe.
I want to switch to preact-iso's router but find it's very cumbersome to get a hold of its route() function in class components (as I can't use useRoute()).
My guess is that preact-iso probably switched to useRoute() for a reason and that the import { route } isn't entirely 'compatible' anymore, but I would appreciate it if there was a better way to get a hold of it :)
Links are automatically intercepted and will invoke route() on any Router with a matching or default route. In any case where you can use an HTML link, it's usually preferable to do so for accessibility reasons:
<ahref="/some/place">Click me!</a>
2. Classes can use context too!
The static .context property allows class components to declare a dependency on a "new" Context (one created via createContext). This lets you access the router context on your class component:
Hooks work inside class components in Preact, it's just not something we document because it might change at some point in the future. However, as it currently stands, you can use hooks inside of a class (and I believe also from within a class constructor!):
Yeah I agree that <a /> is prefered but there are some cases where I need to route() after the user clicks something, I do some work, etc. But absolutely, yes.
Doesn't seem to work for me. I tried your example and somehow this.context is an object with only ["__cC0","__cC1"] as keys. No route.
I must be doing something wrong as the static get context() isn't even being called, it seems :(
As long as I get the context in a component residing in the <LocationProvider />, I can use method #2.
But when I want to route() from the component that contains the <LocationProvider />, I have to fall back to a hack. The use-case here is that I want <App /> to check auth and reroute if the user is not authed.
I used to be able to do something like (real quick-and-dirty pseudo-code):
@rejhgadellaa my suggestion here would be to move LocationProvider out of all of your components, and have one small root component that only renders the providers for your app:
Activity
developit commentedon May 25, 2022
There are a few ways to do this.
1. Prefer HTML links
Links are automatically intercepted and will invoke
route()on any Router with a matching or default route. In any case where you can use an HTML link, it's usually preferable to do so for accessibility reasons:2. Classes can use context too!
The static
.contextproperty allows class components to declare a dependency on a "new" Context (one created viacreateContext). This lets you access the router context on your class component:3. Hack: use the hook to access context
Use the provided
useLocationhook to access context, then access it via a ref from your class component:4. Hack: Use hooks inside your class component
Hooks work inside class components in Preact, it's just not something we document because it might change at some point in the future. However, as it currently stands, you can use hooks inside of a class (and I believe also from within a class constructor!):
rejhgadellaa commentedon May 25, 2022
Thanks for the detailed response!
Yeah I agree that
<a />is prefered but there are some cases where I need toroute()after the user clicks something, I do some work, etc. But absolutely, yes.Doesn't seem to work for me. I tried your example and somehow
this.contextis an object with only["__cC0","__cC1"]as keys. Noroute.I must be doing something wrong as the
static get context()isn't even being called, it seems :(For completeness, this is
render()inindex.js:And then, simplified, what I have in
Home:Thought about doing something like this but thought I'd file a feature request before resorting to hacks :)
This actually works. But yeah, it's a hack.
developit commentedon May 29, 2022
@rejhgadellaa ah! sorry, I messed up the example for
#2- it should becontextType(singular):or, if you'd like to avoid the getter:
rejhgadellaa commentedon Jun 9, 2022
Sorry didn't have time to test this until now.
It works! Thanks!
As long as I get the context in a component residing in the
<LocationProvider />, I can use method#2.But when I want to
route()from the component that contains the<LocationProvider />, I have to fall back to a hack. The use-case here is that I want<App />to check auth and reroute if the user is not authed.I used to be able to do something like (real quick-and-dirty pseudo-code):
but now I have to pull some shenanigans to get a hold of route outside the
<LocationProvider />So my feature request stands, I guess? Would be really nice if we could just import the function and use it anywhere :)
I didn't check, but maybe I could probably do something like calling
history.pushState()to trigger the route?Anyway, thanks for the help so far!
developit commentedon Jun 9, 2022
@rejhgadellaa my suggestion here would be to move LocationProvider out of all of your components, and have one small root component that only renders the providers for your app:
mike-lischke commentedon Feb 25, 2025
Unfortunately, nothing of the given solutions is usable in a TypeScript project.
static context = LocationProvider.ctx;is unkown. Missing correct type definition.The only way to get this to work is to suppress all TS and eslint errors in this file, which is the real hack.
This is what I use now (and suppress TS errors for
Router.Provider, as well ascontext):pallosp commentedon May 27, 2025
Option 2 works when type checking is disabled. I filed preactjs/preact-iso#88 for the missing declaration.