Skip to content

Commit b4ef473

Browse files
committed
Version 6.1.0-noslash.7.0
1 parent e06523f commit b4ef473

File tree

3 files changed

+80
-14
lines changed

3 files changed

+80
-14
lines changed

packages/react-router-dom/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
generatePath,
1313
matchRoutes,
1414
matchPath,
15+
parseLocation,
1516
resolvePath,
1617
renderMatches,
1718
useHref,
@@ -20,6 +21,7 @@ import {
2021
useMatch,
2122
useNavigate,
2223
useNavigationType,
24+
useNavigator,
2325
useOutlet,
2426
useParams,
2527
useResolvedPath,
@@ -60,6 +62,7 @@ export {
6062
generatePath,
6163
matchRoutes,
6264
matchPath,
65+
parseLocation,
6366
renderMatches,
6467
resolvePath,
6568
useHref,
@@ -68,6 +71,7 @@ export {
6871
useMatch,
6972
useNavigate,
7073
useNavigationType,
74+
useNavigator,
7175
useOutlet,
7276
useParams,
7377
useResolvedPath,
@@ -169,7 +173,11 @@ export interface HashRouterProps {
169173
* A <Router> for use in web browsers. Stores the location in the hash
170174
* portion of the URL so it is not sent to the server.
171175
*/
172-
export function HashRouter({ basename, children, window }: HashRouterProps) {
176+
export function HashRouter({
177+
basename = "/",
178+
children,
179+
window
180+
}: HashRouterProps) {
173181
let historyRef = React.useRef<HashHistory>();
174182
if (historyRef.current == null) {
175183
historyRef.current = createHashHistory({ window });

packages/react-router-native/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
generatePath,
2020
matchRoutes,
2121
matchPath,
22+
parseLocation,
2223
resolvePath,
2324
renderMatches,
2425
useHref,
@@ -27,6 +28,7 @@ import {
2728
useMatch,
2829
useNavigate,
2930
useNavigationType,
31+
useNavigator,
3032
useOutlet,
3133
useParams,
3234
useResolvedPath,
@@ -52,6 +54,7 @@ export {
5254
generatePath,
5355
matchRoutes,
5456
matchPath,
57+
parseLocation,
5558
resolvePath,
5659
renderMatches,
5760
useHref,
@@ -60,6 +63,7 @@ export {
6063
useMatch,
6164
useNavigate,
6265
useNavigationType,
66+
useNavigator,
6367
useOutlet,
6468
useParams,
6569
useResolvedPath,

packages/react-router/index.tsx

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ export function Router({
258258
children = null,
259259
location: locationProp,
260260
navigationType = NavigationType.Pop,
261-
navigator,
261+
navigator: navigatorProp,
262262
static: staticProp = false
263263
}: RouterProps): React.ReactElement | null {
264264
invariant(
@@ -267,6 +267,7 @@ export function Router({
267267
` You should never have more than one in your app.`
268268
);
269269

270+
let navigator = useNavigator(navigatorProp, basenameProp);
270271
let basename = normalizePathname(basenameProp);
271272
let navigationContext = React.useMemo(
272273
() => ({ basename, navigator, static: staticProp }),
@@ -277,13 +278,7 @@ export function Router({
277278
locationProp = parsePath(locationProp);
278279
}
279280

280-
let {
281-
pathname = "/",
282-
search = "",
283-
hash = "",
284-
state = null,
285-
key = "default"
286-
} = locationProp;
281+
let { pathname, search, hash, state, key } = parseLocation(locationProp);
287282

288283
let location = React.useMemo(() => {
289284
let trailingPathname = stripBasename(pathname, basename);
@@ -450,6 +445,62 @@ type ParamParseKey<Segment extends string> =
450445
? ParamParseSegment<Segment>
451446
: string;
452447

448+
/**
449+
* Returns a complete Location with an absolute pathname
450+
*/
451+
export function parseLocation({
452+
pathname = "/",
453+
...rest
454+
}: Partial<Location>): Location {
455+
const defaultLocation = {
456+
pathname: "/",
457+
search: "",
458+
hash: "",
459+
state: null,
460+
key: "default"
461+
};
462+
return {
463+
...defaultLocation,
464+
...rest,
465+
pathname: normalizePathnameStart(pathname)
466+
};
467+
}
468+
469+
/**
470+
* Returns a modified navigator to allow relative pathnames
471+
*/
472+
export function useNavigator(
473+
navigator: Navigator,
474+
basename: string
475+
): Navigator {
476+
if (basename !== "") {
477+
return navigator;
478+
}
479+
480+
const makeRelative = (path: Path): Path => {
481+
return {
482+
...path,
483+
pathname: path.pathname.replace(/^\//, "")
484+
};
485+
};
486+
const push = (to: To, state?: any): void => {
487+
navigator.push(makeRelative(resolvePath(to)), state);
488+
};
489+
const replace = (to: To, state?: any): void => {
490+
navigator.replace(makeRelative(resolvePath(to)), state);
491+
};
492+
const createHref = (to: To): string => {
493+
return navigator.createHref(makeRelative(resolvePath(to)));
494+
};
495+
496+
return {
497+
go: navigator.go,
498+
push,
499+
replace,
500+
createHref
501+
};
502+
}
503+
453504
/**
454505
* Returns the current navigation action which describes how the router came to
455506
* the current location, either by a pop, push, or replace on the history stack.
@@ -599,7 +650,6 @@ export function useResolvedPath(to: To): Path {
599650
let routePathnamesJson = JSON.stringify(
600651
matches.map(match => match.pathnameBase)
601652
);
602-
603653
return React.useMemo(
604654
() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname),
605655
[to, routePathnamesJson, locationPathname]
@@ -848,10 +898,11 @@ export function matchRoutes(
848898
locationArg: Partial<Location> | string,
849899
basename = "/"
850900
): RouteMatch[] | null {
851-
let location =
852-
typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
901+
let absolutePathname = parseLocation(
902+
typeof locationArg === "string" ? parsePath(locationArg) : locationArg
903+
).pathname;
853904

854-
let pathname = stripBasename(location.pathname || "/", basename);
905+
let pathname = stripBasename(absolutePathname, basename);
855906

856907
if (pathname == null) {
857908
return null;
@@ -1353,8 +1404,11 @@ function stripBasename(pathname: string, basename: string): string | null {
13531404
const joinPaths = (paths: string[]): string =>
13541405
paths.join("/").replace(/\/\/+/g, "/");
13551406

1407+
const normalizePathnameStart = (pathname: string): string =>
1408+
pathname.replace(/^\/*/, "/");
1409+
13561410
const normalizePathname = (pathname: string): string =>
1357-
pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
1411+
normalizePathnameStart(pathname.replace(/\/+$/, ""));
13581412

13591413
const normalizeSearch = (search: string): string =>
13601414
!search || search === "?"

0 commit comments

Comments
 (0)