Closed crapthings closed 8 years ago
Hmm - not sure what you mean. You can use nested routes and they will be resolved the same as any component:
<Router>
<div path="/1">
<Router>
<div path="/*/a">One A</div>
<div path="/*/b">One B</div>
</Router>
</div>
<div path="/2">
<Router>
<div path="/*/a">Two A</div>
<div path="/*/b">Two B</div>
</Router>
</div>
</Router>
I think I'm going to close this for now, since I don't want to re-implement react-router
, but rather provide a simple mapping of the browser's URL to props with pattern matching. react-router
is a great project, and I would rather people who need that level of flexibility just use it directly (it works with preact-compat
) to benefit from all of @mjackson, @ryanflorence & co's work.
@crapthings - i'm a bit late to answer here, but this is how you'd convert a react-router
layout to preact-router
:
<Router history={browserHistory}>
<Route path='/' component={Layout}>
<IndexRoute component={RecipeList} />
<Route path="/:name" component={Recipe} />
</Route>
</Router>
<Layout>
<Router>
<RecipeList path="/" />
<Recipe path="/:name" />
</Router>
</Layout>
@pearofducks thanks for the example, I think that'll be useful for anyone finding this issue from Google. Cheers!
@pearofduck, @developit
this is it ! thanks~
Either things have changed since 2016 or I didn't understand how to implement it, but @pearofducks' solution did not work for me for a few reasons, namely:
Router
s they don't see each others' routes, so if you have a NotFoundPage
component in one of them it will always render when you visit the routes that are outside of its scope.What worked for me was to decorate the components with their respective layouts, for example:
// src/components/router.tsx
import { FunctionalComponent, h } from "preact";
import { Route, Router } from "preact-router";
import Recipe from "../routes/recipe";
import NotFoundPage from "../routes/notfound";
import Collection from "./layout/collection";
import Detail from "./layout/detail";
export default (() => {
const RecipeCollection = Collection(Recipe);
const RecipeDetail = Detail(Recipe);
return (
<Router>
<Route path="/recipes/" component={RecipeCollection} />
<Route path="/recipes/:slug" component={RecipeDetail} />
<NotFoundPage default />
</Router>
);
}) as FunctionalComponent;
Then the decorators are a simple function that receives a component and returns it decorated with the corresponding layout:
// src/components/layout/detail/index.tsx
import { FunctionalComponent, h } from "preact";
import DetailLayout from "./component";
export default (Component: FunctionalComponent): FunctionalComponent => {
return props => (
<DetailLayout>
<Component {...props} />
</DetailLayout>
);
};
The same for the collection:
// src/components/layout/collection/index.tsx
import { FunctionalComponent, h } from "preact";
import CollectionLayout from "./component";
export default (Component: FunctionalComponent): FunctionalComponent => {
return props => (
<CollectionLayout>
<Component {...props} />
</CollectionLayout>
);
};
Since this is the only reference I could find to this problem for preact specifically I leave my solution here. I hope this helps anyone looking to achieve this without having to resort to preact-compat
. I'm very new to preact so I would really appreciate feedback on this approach.
Here is a workaround using preact signals (see below).
Layout does not need to be wrapped into Router
, can use multiple (also nested) Layouts
export const url = signal('')
import { url } from './store/router';
function App(){
function handleRoute({ url: _url }: { url: string }){
url.value = _url
}
return (
<>
<Layout>
<Router onChange={e => handleRoute(e)}>
<Route path="/search" component={Search}/>
<Route path="/profile" component={Profile}/>
</Router>
</Layout>
</>
)
}
import { url } from './store/router';
function Layout({children}){
return (
{ url.value? === '/search' && (
<div>
Search layout
<div>{children}<div>
</div>
}
{ ['/profile', '/home'].includes(url.value) && (
<div>
Profile and home layout
<div>{children}<div>
</div>
}
)
}
is this same to react router ?