Skip to content

Commit 8b766a9

Browse files
committedMar 18, 2024
restore params into root
1 parent d1a8aab commit 8b766a9

File tree

5 files changed

+64
-58
lines changed

5 files changed

+64
-58
lines changed
 

‎.changeset/olive-books-push.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@solidjs/router": patch
3+
---
4+
5+
restore params into root

‎src/routers/components.tsx

+11-25
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import type {
3232
RouteSectionProps,
3333
Location
3434
} from "../types.js";
35-
import { createMemoObject } from "../utils.js";
3635

3736
export type BaseRouterProps = {
3837
base?: string;
@@ -53,16 +52,14 @@ export const createRouterComponent = (router: RouterIntegration) => (props: Base
5352

5453
const branches = createMemo(() => createBranches(routeDefs(), props.base || ""));
5554
let context: Owner;
56-
const routerState = createRouterContext(router, () => context, branches, {
55+
const routerState = createRouterContext(router, branches, () => context, {
5756
base,
5857
singleFlight: props.singleFlight
5958
});
60-
const location = routerState.location;
6159
router.create && router.create(routerState);
62-
6360
return (
6461
<RouterContextObj.Provider value={routerState}>
65-
<Root location={location} root={props.root} load={props.rootLoad}>
62+
<Root routerState={routerState} root={props.root} load={props.rootLoad}>
6663
{(context = getOwner()!) && null}
6764
<Routes routerState={routerState} branches={branches()} />
6865
</Root>
@@ -71,19 +68,20 @@ export const createRouterComponent = (router: RouterIntegration) => (props: Base
7168
};
7269

7370
function Root(props: {
74-
location: Location<unknown>;
71+
routerState: RouterContext;
7572
root?: Component<RouteSectionProps>;
7673
load?: RouteLoadFunc;
7774
children: JSX.Element;
7875
}) {
79-
const location = props.location;
76+
const location = props.routerState.location;
77+
const params = props.routerState.params;
8078
const data = createMemo(
81-
() => props.load && untrack(() => props.load!({ params: {}, location, intent: "preload" }))
79+
() => props.load && untrack(() => props.load!({ params, location, intent: "preload" }))
8280
);
8381
return (
8482
<Show when={props.root} keyed fallback={props.children}>
8583
{Root => (
86-
<Root params={{}} location={location} data={data()}>
84+
<Root params={params} location={location} data={data()}>
8785
{props.children}
8886
</Root>
8987
)}
@@ -92,10 +90,6 @@ function Root(props: {
9290
}
9391

9492
function Routes(props: { routerState: RouterContext; branches: Branch[] }) {
95-
const matches = createMemo(() =>
96-
getRouteMatches(props.branches, props.routerState.location.pathname)
97-
);
98-
9993
if (isServer) {
10094
const e = getRequestEvent();
10195
if (e && e.router && e.router.dataOnly) {
@@ -104,27 +98,20 @@ function Routes(props: { routerState: RouterContext; branches: Branch[] }) {
10498
}
10599
e &&
106100
((e.router || (e.router = {})).matches ||
107-
(e.router.matches = matches().map(({ route, path, params }) => ({
101+
(e.router.matches = props.routerState.matches().map(({ route, path, params }) => ({
108102
path: route.originalPath,
109103
pattern: route.pattern,
110104
match: path,
111105
params,
112106
info: route.info
113107
}))));
114108
}
115-
const params = createMemoObject(() => {
116-
const m = matches();
117-
const params: Params = {};
118-
for (let i = 0; i < m.length; i++) {
119-
Object.assign(params, m[i].params);
120-
}
121-
return params;
122-
});
109+
123110
const disposers: (() => void)[] = [];
124111
let root: RouteContext | undefined;
125112

126113
const routeStates = createMemo(
127-
on(matches, (nextMatches, prevMatches, prev: RouteContext[] | undefined) => {
114+
on(props.routerState.matches, (nextMatches, prevMatches, prev: RouteContext[] | undefined) => {
128115
let equal = prevMatches && nextMatches.length === prevMatches.length;
129116
const next: RouteContext[] = [];
130117
for (let i = 0, len = nextMatches.length; i < len; i++) {
@@ -145,8 +132,7 @@ function Routes(props: { routerState: RouterContext; branches: Branch[] }) {
145132
props.routerState,
146133
next[i - 1] || props.routerState.base,
147134
createOutlet(() => routeStates()[i + 1]),
148-
() => matches()[i],
149-
params
135+
() => props.routerState.matches()[i]
150136
);
151137
});
152138
}

‎src/routing.ts

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { JSX, Accessor, getOwner, runWithOwner } from "solid-js";
1+
import { JSX, Accessor, runWithOwner } from "solid-js";
22
import {
33
createComponent,
44
createContext,
@@ -91,7 +91,7 @@ export const useMatch = <S extends string>(path: () => S, matchFilters?: MatchFi
9191
});
9292
};
9393

94-
export const useParams = <T extends Params>() => useRoute().params as T;
94+
export const useParams = <T extends Params>() => useRouter().params as T;
9595

9696
export const useSearchParams = <T extends Params>(): [
9797
Partial<T>,
@@ -271,8 +271,8 @@ export function getIntent() {
271271

272272
export function createRouterContext(
273273
integration: RouterIntegration,
274+
branches: () => Branch[],
274275
getContext?: () => any,
275-
getBranches?: () => Branch[],
276276
options: { base?: string; singleFlight?: boolean } = {}
277277
): RouterContext {
278278
const {
@@ -306,9 +306,19 @@ export function createRouterContext(
306306
const referrers: LocationChange[] = [];
307307
const submissions = createSignal<Submission<any, any>[]>(isServer ? initFromFlash() : []);
308308

309+
const matches = createMemo(() => getRouteMatches(branches(), location.pathname));
310+
311+
const params = createMemoObject(() => {
312+
const m = matches();
313+
const params: Params = {};
314+
for (let i = 0; i < m.length; i++) {
315+
Object.assign(params, m[i].params);
316+
}
317+
return params;
318+
});
319+
309320
const baseRoute: RouteContext = {
310321
pattern: basePath,
311-
params: {},
312322
path: () => basePath,
313323
outlet: () => null,
314324
resolvePath(to: string) {
@@ -337,10 +347,12 @@ export function createRouterContext(
337347
return {
338348
base: baseRoute,
339349
location,
350+
params,
340351
isRouting,
341352
renderPath,
342353
parsePath,
343354
navigatorFactory,
355+
matches,
344356
beforeLeave,
345357
preloadRoute,
346358
singleFlight: options.singleFlight === undefined ? true : options.singleFlight,
@@ -436,7 +448,7 @@ export function createRouterContext(
436448
}
437449

438450
function preloadRoute(url: URL, preloadData: boolean) {
439-
const matches = getRouteMatches(getBranches!(), url.pathname);
451+
const matches = getRouteMatches(branches(), url.pathname);
440452
const prevIntent = intent;
441453
intent = "preload";
442454
for (let match in matches) {
@@ -478,9 +490,8 @@ export function createRouteContext(
478490
parent: RouteContext,
479491
outlet: () => JSX.Element,
480492
match: () => RouteMatch,
481-
params: Params
482493
): RouteContext {
483-
const { base, location } = router;
494+
const { base, location, params } = router;
484495
const { pattern, component, load } = match().route;
485496
const path = createMemo(() => match().path);
486497

@@ -493,7 +504,6 @@ export function createRouteContext(
493504
parent,
494505
pattern,
495506
path,
496-
params,
497507
outlet: () =>
498508
component
499509
? createComponent(component, {

‎src/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ export interface RouteContext {
145145
parent?: RouteContext;
146146
child?: RouteContext;
147147
pattern: string;
148-
params: Params;
149148
path: () => string;
150149
outlet: () => JSX.Element;
151150
resolvePath(to: string): string | undefined;
@@ -161,8 +160,10 @@ export interface RouterUtils {
161160
export interface RouterContext {
162161
base: RouteContext;
163162
location: Location;
163+
params: Params;
164164
navigatorFactory: NavigatorFactory;
165165
isRouting: () => boolean;
166+
matches: () => RouteMatch[];
166167
renderPath(path: string): string;
167168
parsePath(str: string): string;
168169
beforeLeave: BeforeLeaveLifecycle;

‎test/router.spec.ts

+28-24
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,35 @@ import { createRouterContext } from "../src/routing.js";
33
import type { LocationChange } from "../src/types.js";
44
import { createAsyncRoot, createCounter, waitFor } from "./helpers.js";
55

6-
const fakeBranches = () => []
7-
const fakeContext = () => ({})
6+
const fakeBranches = () => [];
7+
const fakeContext = () => ({});
88

99
describe("Router should", () => {
1010
describe("have member `base` which should", () => {
1111
test(`have a default path when base path is not defined`, () => {
1212
createRoot(() => {
1313
const signal = createSignal<LocationChange>({ value: "" });
14-
const { base } = createRouterContext({ signal });
14+
const { base } = createRouterContext({ signal }, fakeBranches);
1515
expect(base.path()).toBe("/");
1616
});
1717
});
1818

1919
test(`have a normalized version of the base path when defined`, () => {
2020
createRoot(() => {
2121
const signal = createSignal<LocationChange>({ value: "" });
22-
const { base } = createRouterContext({ signal }, fakeContext, fakeBranches, { base: "base" });
22+
const { base } = createRouterContext({ signal }, fakeBranches, fakeContext, {
23+
base: "base"
24+
});
2325
expect(base.path()).toBe("/base");
2426
});
2527
});
2628

2729
test(`throw when the base path is invalid`, () => {
2830
createRoot(() => {
2931
const signal = createSignal<LocationChange>({ value: "" });
30-
expect(() => createRouterContext({ signal }, fakeContext, fakeBranches, { base: "http://example.com" })).toThrow();
32+
expect(() =>
33+
createRouterContext({ signal }, fakeBranches, fakeContext, { base: "http://example.com" })
34+
).toThrow();
3135
});
3236
});
3337
});
@@ -38,7 +42,7 @@ describe("Router should", () => {
3842
const signal = createSignal<LocationChange>({
3943
value: "/foo/bar?hello=world"
4044
});
41-
const { location } = createRouterContext({ signal });
45+
const { location } = createRouterContext({ signal }, fakeBranches);
4246
expect(location.pathname).toBe("/foo/bar");
4347
expect(location.search).toBe("?hello=world");
4448
});
@@ -51,7 +55,7 @@ describe("Router should", () => {
5155
const signal = createSignal<LocationChange>({
5256
value: "/foo/bar?hello=world"
5357
});
54-
const { location } = createRouterContext({ signal });
58+
const { location } = createRouterContext({ signal }, fakeBranches);
5559
expect(location.pathname).toBe("/foo/bar");
5660
signal[1]({ value: expected + "?hello=world" });
5761
waitFor(() => signal[0]().value === expected + "?hello=world").then(() => {
@@ -65,7 +69,7 @@ describe("Router should", () => {
6569
const signal = createSignal<LocationChange>({
6670
value: "/foo/bar?hello=world"
6771
});
68-
const { location } = createRouterContext({ signal });
72+
const { location } = createRouterContext({ signal }, fakeBranches);
6973
const count = createCounter(() => location.pathname);
7074
expect(location.pathname).toBe("/foo/bar");
7175
signal[1]({ value: "/foo/bar?fizz=buzz" });
@@ -78,7 +82,7 @@ describe("Router should", () => {
7882
const signal = createSignal<LocationChange>({
7983
value: "/foo bar+baz"
8084
});
81-
const { location } = createRouterContext({ signal });
85+
const { location } = createRouterContext({ signal }, fakeBranches);
8286
expect(location.pathname).toBe("/foo%20bar+baz");
8387
}));
8488
}); // end of "contain property 'pathname'"
@@ -90,7 +94,7 @@ describe("Router should", () => {
9094
const signal = createSignal<LocationChange>({
9195
value: "/foo/bar?hello=world"
9296
});
93-
const { location } = createRouterContext({ signal });
97+
const { location } = createRouterContext({ signal }, fakeBranches);
9498

9599
expect(location.search).toBe("?hello=world");
96100
signal[1]({ value: "/foo/baz" + expected });
@@ -106,7 +110,7 @@ describe("Router should", () => {
106110
const signal = createSignal<LocationChange>({
107111
value: "/foo/bar?hello=world"
108112
});
109-
const { location } = createRouterContext({ signal });
113+
const { location } = createRouterContext({ signal }, fakeBranches);
110114
const count = createCounter(() => location.search);
111115

112116
expect(location.search).toBe("?hello=world");
@@ -120,7 +124,7 @@ describe("Router should", () => {
120124
const signal = createSignal<LocationChange>({
121125
value: "/foo?hello+world=bar+baz"
122126
});
123-
const { location } = createRouterContext({ signal });
127+
const { location } = createRouterContext({ signal }, fakeBranches);
124128
expect(location.search).toBe("?hello+world=bar+baz");
125129
}));
126130
}); //end of "contain property 'search'"
@@ -131,7 +135,7 @@ describe("Router should", () => {
131135
const signal = createSignal<LocationChange>({
132136
value: "/foo#bar baz"
133137
});
134-
const { location } = createRouterContext({ signal });
138+
const { location } = createRouterContext({ signal }, fakeBranches);
135139
expect(location.hash).toBe("#bar%20baz");
136140
}));
137141
}); // end of "contain property 'hash'"
@@ -142,7 +146,7 @@ describe("Router should", () => {
142146
const signal = createSignal<LocationChange>({
143147
value: "/foo/bar?hello=world&fizz=buzz"
144148
});
145-
const { location } = createRouterContext({ signal });
149+
const { location } = createRouterContext({ signal }, fakeBranches);
146150
expect(location.query.hello).toEqual("world");
147151
expect(location.query.fizz).toEqual("buzz");
148152
});
@@ -153,7 +157,7 @@ describe("Router should", () => {
153157
const signal = createSignal<LocationChange>({
154158
value: "/foo/bar?hello=world"
155159
});
156-
const { location } = createRouterContext({ signal });
160+
const { location } = createRouterContext({ signal }, fakeBranches);
157161

158162
expect(location.query.hello).toEqual("world");
159163
signal[1]({ value: "/foo/bar?hello=world&fizz=buzz" });
@@ -169,7 +173,7 @@ describe("Router should", () => {
169173
const signal = createSignal<LocationChange>({
170174
value: "/foo/bar?hello=world"
171175
});
172-
const { location } = createRouterContext({ signal });
176+
const { location } = createRouterContext({ signal }, fakeBranches);
173177
const count = createCounter(() => location.query.hello);
174178

175179
expect(location.query.hello).toEqual("world");
@@ -189,7 +193,7 @@ describe("Router should", () => {
189193
const signal = createSignal<LocationChange>({
190194
value: "/foo/bar?hello=world"
191195
});
192-
const { location } = createRouterContext({ signal });
196+
const { location } = createRouterContext({ signal }, fakeBranches);
193197
const count = createCounter(() => location.query.hello);
194198

195199
expect(location.query.hello).toEqual("world");
@@ -211,7 +215,7 @@ describe("Router should", () => {
211215
const signal = createSignal<LocationChange>({
212216
value: "/"
213217
});
214-
const { location, navigatorFactory } = createRouterContext({ signal });
218+
const { location, navigatorFactory } = createRouterContext({ signal }, fakeBranches);
215219
const navigate = navigatorFactory();
216220

217221
expect(location.pathname).toBe("/");
@@ -228,7 +232,7 @@ describe("Router should", () => {
228232
const signal = createSignal<LocationChange>({
229233
value: "/foo/bar"
230234
});
231-
const { location, navigatorFactory } = createRouterContext({ signal });
235+
const { location, navigatorFactory } = createRouterContext({ signal }, fakeBranches);
232236
const navigate = navigatorFactory();
233237
const count = createCounter(() => location.pathname);
234238

@@ -246,7 +250,7 @@ describe("Router should", () => {
246250
const signal = createSignal<LocationChange>({
247251
value: "/"
248252
});
249-
const { navigatorFactory } = createRouterContext({ signal });
253+
const { navigatorFactory } = createRouterContext({ signal }, fakeBranches);
250254
const navigate = navigatorFactory();
251255
expect(signal[0]().value).toBe("/");
252256
navigate("/foo/bar");
@@ -263,7 +267,7 @@ describe("Router should", () => {
263267
const state = { foo: "bar" };
264268
const signal = createSignal<LocationChange>({ value: "/" });
265269

266-
const { location, navigatorFactory } = createRouterContext({ signal });
270+
const { location, navigatorFactory } = createRouterContext({ signal }, fakeBranches);
267271
const navigate = navigatorFactory();
268272

269273
expect(location.state).toBeUndefined();
@@ -281,7 +285,7 @@ describe("Router should", () => {
281285
const state = { foo: "bar" };
282286
const signal = createSignal<LocationChange>({ value: "/" });
283287

284-
const { location, navigatorFactory } = createRouterContext({ signal });
288+
const { location, navigatorFactory } = createRouterContext({ signal }, fakeBranches);
285289
const navigate = navigatorFactory();
286290

287291
expect(location.state).toBeUndefined();
@@ -299,7 +303,7 @@ describe("Router should", () => {
299303
const signal = createSignal<LocationChange>({
300304
value: "/"
301305
});
302-
const { navigatorFactory } = createRouterContext({ signal });
306+
const { navigatorFactory } = createRouterContext({ signal }, fakeBranches);
303307
const navigate = navigatorFactory();
304308

305309
expect(signal[0]()).toEqual({ value: "/" });
@@ -321,7 +325,7 @@ describe("Router should", () => {
321325
const signal = createSignal<LocationChange>({
322326
value: "/"
323327
});
324-
const { navigatorFactory } = createRouterContext({ signal });
328+
const { navigatorFactory } = createRouterContext({ signal }, fakeBranches);
325329
const navigate = navigatorFactory();
326330
function pushAlot() {
327331
for (let i = 0; i < 101; i++) {

0 commit comments

Comments
 (0)
Please sign in to comment.