-
-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Router: Easier access to route() in class components #930
Comments
There are a few ways to do this. 1. Prefer HTML linksLinks are automatically intercepted and will invoke <a href="/some/place">Click me!</a> 2. Classes can use context too!The static import { Component } from 'preact';
import { LocationProvider } from 'preact-iso';
class C extends Component {
static context = LocationProvider.ctx;
render() {
return (
<div onClick={ event => this.context.route('/some/place') }>Click me!</div>
);
}
} 3. Hack: use the hook to access contextUse the provided import { Component, createRef } from 'preact';
import { forwardRef } from 'preact-forwardref';
import { useLocation } from 'preact-iso';
const WithLocation = forwardRef(({ ref }) => {
ref.current = useLocation();
});
class C extends Component {
router = createRef();
render() {
return (
<>
<WithLocation ref={this.router} />
<div onClick={ event => this.router.current.route('/some/place') }>Click me!</div>
</>
);
}
} 4. Hack: Use hooks inside your class componentHooks 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!): import { Component } from 'preact';
import { useLocation } from 'preact-iso';
class C extends Component {
render() {
const { route } = useLocation();
return (
<div onClick={ event => route('/some/place') }>Click me!</div>
);
}
} |
Thanks for the detailed response!
I must be doing something wrong as the For completeness, this is <div id="app">
<LocationProvider>
<ErrorBoundary>
<Router onRouteChange={this._onRouteChange}>
<Home path="/" />
</Router>
</ErrorBoundary>
</LocationProvider>
</div> And then, simplified, what I have in import { Component } from 'preact';
import { LocationProvider } from 'preact-iso';
export default class Home extends Component {
static get context() {
return LocationProvider.ctx;
}
render() {
return (
<div onClick={ event => console.log( Object.keys(this.context) ) }>Click me!</div>
);
}
}
|
@rejhgadellaa ah! sorry, I messed up the example for class C extends Component {
static get contextType() { return LocationProvider.ctx; }
render() {
// ...
}
} or, if you'd like to avoid the getter: class C extends Component {
render() {
// ...
}
}
C.contextType = LocationProvider.ctx; |
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 But when I want to I used to be able to do something like (real quick-and-dirty pseudo-code): import { route } from 'preact-router';
class C extends Component {
componentDidMount() {
( async () => {
const isAuthed = await checkAuth()
if (!isAuthed) route('/login');
})();
}
render() {
return (
<LocationProdiver>
<ErrorBoundary>
<Router />
</ErrorBoundary>
</LocationProdiver>
)
}
} but now I have to pull some shenanigans to get a hold of route outside the 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 Anyway, thanks for the help so far! |
@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: function C() {
return (
<ErrorBoundary>
<Router />
</ErrorBoundary>
);
}
export default function App() {
return (
<LocationProvider>
<C />
</LocationProvider>
);
} |
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 useuseRoute()
).I've managed to do it, but it's not pretty:
Describe the solution you'd like
In preact-router, I could just do:
and then use
route()
pretty much anywhere.My guess is that preact-iso probably switched to
useRoute()
for a reason and that theimport { route }
isn't entirely 'compatible' anymore, but I would appreciate it if there was a better way to get a hold of it :)Thanks!
The text was updated successfully, but these errors were encountered: