Skip to content

Commit 02d84b4

Browse files
committed
fix: Nested routing
1 parent e46f6a0 commit 02d84b4

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

src/router.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { h, Fragment, createContext, cloneElement, toChildArray } from 'preact';
1+
import { h, createContext, cloneElement, toChildArray } from 'preact';
22
import { useContext, useMemo, useReducer, useLayoutEffect, useRef } from 'preact/hooks';
33

44
/**
@@ -138,6 +138,7 @@ export function Router(props) {
138138
if (!url) {
139139
throw new Error(`preact-iso's <Router> must be used within a <LocationProvider>, see: https://github.com/preactjs/preact-iso#locationprovider`);
140140
}
141+
const { rest = path } = useContext(RouterContext);
141142

142143
const isLoading = useRef(false);
143144
const prevRoute = useRef(path);
@@ -158,11 +159,11 @@ export function Router(props) {
158159
let pathRoute, defaultRoute, matchProps;
159160
toChildArray(props.children).some((/** @type {VNode<any>} */ vnode) => {
160161
const matches = exec(
161-
path,
162+
rest,
162163
vnode.props.path,
163164
(matchProps = {
164165
...vnode.props,
165-
path,
166+
path: rest,
166167
pathParams : Object.assign({}, pathParams),
167168
searchParams,
168169
}));
@@ -178,7 +179,7 @@ export function Router(props) {
178179
const routeChanged = useMemo(() => {
179180
prev.current = cur.current;
180181

181-
cur.current = /** @type {VNode<any>} */ (h(Fragment, { key: path }, incoming));
182+
cur.current = /** @type {VNode<any>} */ (h(RouterContext.Provider, { value: matchProps }, incoming));
182183

183184
// Only mark as an update if the route component changed.
184185
const outgoing = prev.current && prev.current.props.children;
@@ -292,6 +293,9 @@ Router.Provider = LocationProvider;
292293
LocationProvider.ctx = createContext(
293294
/** @type {import('./router.d.ts').LocationHook & { wasPush: boolean }} */ ({})
294295
);
296+
const RouterContext = createContext(
297+
/** @type {{ rest: string }} */ ({})
298+
);
295299

296300
export const Route = props => h(props.component, props);
297301

test/router.test.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -876,8 +876,8 @@ describe('Router', () => {
876876
const Inner = () => (
877877
<Router>
878878
<Route
879-
path="/bob"
880-
component={() => null}
879+
path="/baz"
880+
component={() => <h1>Baz</h1>}
881881
/>
882882
</Router>
883883
);
@@ -887,15 +887,16 @@ describe('Router', () => {
887887
<Router>
888888
<Route path="/foo/:id/*" component={Inner} />
889889
</Router>
890-
<a href="/foo/bar/bob"></a>
890+
<a href="/foo/bar/baz"></a>
891891
<ShallowLocation />
892892
</LocationProvider>,
893893
scratch
894894
);
895895

896-
scratch.querySelector('a[href="/foo/bar/bob"]').click();
896+
scratch.querySelector('a[href="/foo/bar/baz"]').click();
897897
await sleep(1);
898-
expect(loc).to.deep.include({ path: '/foo/bar/bob', pathParams: { id: 'bar' }, searchParams: {} });
898+
expect(loc).to.deep.include({ path: '/foo/bar/baz', pathParams: { id: 'bar' }, searchParams: {} });
899+
expect(scratch).to.have.property('textContent', 'Baz');
899900
});
900901

901902
it('should append params in nested routes', async () => {

0 commit comments

Comments
 (0)