Skip to content

Commit c7c0dac

Browse files
committed
fix: Nested routing
1 parent a06b641 commit c7c0dac

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

src/router.js

Lines changed: 7 additions & 3 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
/**
@@ -117,6 +117,7 @@ export function Router(props) {
117117
const [c, update] = useReducer(c => c + 1, 0);
118118

119119
const { url, path, pathParams, searchParams, wasPush } = useLocation();
120+
const { rest = path } = useContext(RouterContext);
120121

121122
const isLoading = useRef(false);
122123
const prevRoute = useRef(path);
@@ -136,7 +137,7 @@ export function Router(props) {
136137

137138
let pathRoute, defaultRoute, matchProps;
138139
toChildArray(props.children).some((/** @type {VNode<any>} */ vnode) => {
139-
const matches = exec(path, vnode.props.path, (matchProps = { ...vnode.props, path, pathParams, searchParams }));
140+
const matches = exec(rest, vnode.props.path, (matchProps = { ...vnode.props, path: rest, pathParams, searchParams }));
140141
if (matches) return (pathRoute = cloneElement(vnode, matchProps));
141142
if (vnode.props.default) defaultRoute = cloneElement(vnode, matchProps);
142143
});
@@ -149,7 +150,7 @@ export function Router(props) {
149150
const routeChanged = useMemo(() => {
150151
prev.current = cur.current;
151152

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

154155
// Only mark as an update if the route component changed.
155156
const outgoing = prev.current && prev.current.props.children;
@@ -263,6 +264,9 @@ Router.Provider = LocationProvider;
263264
LocationProvider.ctx = createContext(
264265
/** @type {import('./router.d.ts').LocationHook & { wasPush: boolean }} */ ({})
265266
);
267+
const RouterContext = createContext(
268+
/** @type {{ rest: string }} */ ({})
269+
);
266270

267271
export const Route = props => h(props.component, props);
268272

test/router.test.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -816,8 +816,8 @@ describe('Router', () => {
816816
const Inner = () => (
817817
<Router>
818818
<Route
819-
path="/bob"
820-
component={() => null}
819+
path="/baz"
820+
component={() => <h1>Baz</h1>}
821821
/>
822822
</Router>
823823
);
@@ -827,15 +827,16 @@ describe('Router', () => {
827827
<Router>
828828
<Route path="/foo/:id/*" component={Inner} />
829829
</Router>
830-
<a href="/foo/bar/bob"></a>
830+
<a href="/foo/bar/baz"></a>
831831
<ShallowLocation />
832832
</LocationProvider>,
833833
scratch
834834
);
835835

836-
scratch.querySelector('a[href="/foo/bar/bob"]').click();
836+
scratch.querySelector('a[href="/foo/bar/baz"]').click();
837837
await sleep(1);
838-
expect(loc).to.deep.include({ path: '/foo/bar/bob', pathParams: { id: 'bar' }, searchParams: {} });
838+
expect(loc).to.deep.include({ path: '/foo/bar/baz', pathParams: { id: 'bar' }, searchParams: {} });
839+
expect(scratch).to.have.property('textContent', 'Baz');
839840
});
840841

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

0 commit comments

Comments
 (0)