Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
- timdorr
- turansky
- sergiodxa
- thejohnhoffer
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "next",
"history": "^5.0.0",
"history-noslash": "^5.2.0-noslash.2.0",
Copy link
Author

@thejohnhoffer thejohnhoffer Dec 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PR #911 of history is merged, I’d update this dependency.

"jest": "^26.6.3",
"jsonfile": "^6.1.0",
"metro-react-native-babel-preset": "^0.57.0",
Expand Down
19 changes: 15 additions & 4 deletions packages/react-router-dom/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import * as React from "react";
import type { BrowserHistory, HashHistory, History } from "history";
import { createBrowserHistory, createHashHistory, createPath } from "history";
import type { BrowserHistory, HashHistory, History } from "history-noslash";
import {
createBrowserHistory,
createHashHistory,
createPath
} from "history-noslash";
import {
MemoryRouter,
Navigate,
Expand All @@ -12,6 +16,7 @@ import {
generatePath,
matchRoutes,
matchPath,
parseLocation,
resolvePath,
renderMatches,
useHref,
Expand Down Expand Up @@ -60,6 +65,7 @@ export {
generatePath,
matchRoutes,
matchPath,
parseLocation,
renderMatches,
resolvePath,
useHref,
Expand Down Expand Up @@ -169,10 +175,15 @@ export interface HashRouterProps {
* A <Router> for use in web browsers. Stores the location in the hash
* portion of the URL so it is not sent to the server.
*/
export function HashRouter({ basename, children, window }: HashRouterProps) {
export function HashRouter({
basename = "/",
children,
window
}: HashRouterProps) {
let historyRef = React.useRef<HashHistory>();
let hashRoot = basename === "" ? "" : "/";
if (historyRef.current == null) {
historyRef.current = createHashHistory({ window });
historyRef.current = createHashHistory({ window, hashRoot });
}

let history = historyRef.current;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-router-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"unpkg": "./umd/react-router-dom.production.min.js",
"dependencies": {
"react-router": "6.0.2",
"history": "^5.1.0"
"history-noslash": "^5.2.0-noslash.2.0"
},
"peerDependencies": {
"react": ">=16.8",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-router-dom/server.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { Action, Location, To, createPath, parsePath } from "history";
import { Action, Location, To, createPath, parsePath } from "history-noslash";
import { Router } from "react-router-dom";

export interface StaticRouterProps {
Expand Down
2 changes: 2 additions & 0 deletions packages/react-router-native/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
generatePath,
matchRoutes,
matchPath,
parseLocation,
resolvePath,
renderMatches,
useHref,
Expand Down Expand Up @@ -52,6 +53,7 @@ export {
generatePath,
matchRoutes,
matchPath,
parseLocation,
resolvePath,
renderMatches,
useHref,
Expand Down
46 changes: 32 additions & 14 deletions packages/react-router/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import type {
MemoryHistory,
Path,
To
} from "history";
} from "history-noslash";
import {
Action as NavigationType,
createMemoryHistory,
parsePath
} from "history";
} from "history-noslash";

export type { Location, Path, To, NavigationType };

Expand Down Expand Up @@ -277,13 +277,7 @@ export function Router({
locationProp = parsePath(locationProp);
}

let {
pathname = "/",
search = "",
hash = "",
state = null,
key = "default"
} = locationProp;
let { pathname, search, hash, state, key } = parseLocation(locationProp);

let location = React.useMemo(() => {
let trailingPathname = stripBasename(pathname, basename);
Expand Down Expand Up @@ -450,6 +444,27 @@ type ParamParseKey<Segment extends string> =
? ParamParseSegment<Segment>
: string;

/**
* Returns a complete Location with an absolute pathname
*/
export function parseLocation({
pathname = "/",
...rest
}: Partial<Location>): Location {
const defaultLocation = {
pathname: "/",
search: "",
hash: "",
state: null,
key: "default"
};
return {
...defaultLocation,
...rest,
pathname: normalizePathnameStart(pathname)
};
}

/**
* Returns the current navigation action which describes how the router came to
* the current location, either by a pop, push, or replace on the history stack.
Expand Down Expand Up @@ -599,7 +614,6 @@ export function useResolvedPath(to: To): Path {
let routePathnamesJson = JSON.stringify(
matches.map(match => match.pathnameBase)
);

return React.useMemo(
() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname),
[to, routePathnamesJson, locationPathname]
Expand Down Expand Up @@ -848,10 +862,11 @@ export function matchRoutes(
locationArg: Partial<Location> | string,
basename = "/"
): RouteMatch[] | null {
let location =
typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
let absolutePathname = parseLocation(
typeof locationArg === "string" ? parsePath(locationArg) : locationArg
).pathname;

let pathname = stripBasename(location.pathname || "/", basename);
let pathname = stripBasename(absolutePathname, basename);

if (pathname == null) {
return null;
Expand Down Expand Up @@ -1353,8 +1368,11 @@ function stripBasename(pathname: string, basename: string): string | null {
const joinPaths = (paths: string[]): string =>
paths.join("/").replace(/\/\/+/g, "/");

const normalizePathnameStart = (pathname: string): string =>
pathname.replace(/^\/*/, "/");

const normalizePathname = (pathname: string): string =>
pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
normalizePathnameStart(pathname.replace(/\/+$/, ""));

const normalizeSearch = (search: string): string =>
!search || search === "?"
Expand Down
2 changes: 1 addition & 1 deletion packages/react-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"react": ">=16.8"
},
"dependencies": {
"history": "^5.1.0"
"history-noslash": "^5.2.0-noslash.2.0"
},
"sideEffects": false,
"keywords": [
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4469,10 +4469,10 @@ hermes-engine@^0.2.1:
resolved "https://registry.npmjs.org/hermes-engine/-/hermes-engine-0.2.1.tgz"
integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ==

history@^5.0.0:
version "5.0.2"
resolved "https://registry.npmjs.org/history/-/history-5.0.2.tgz"
integrity sha512-mBsCaXLUOD9x4YMQlyKHkHqFQlgG0ISle3edo6npJ1N2kb8lcGkmPUHpS4WjmrB64s5H70UniAxKmGDHJkstUQ==
history-noslash@^5.2.0-noslash.2.0:
version "5.2.0-noslash.2.0"
resolved "https://registry.yarnpkg.com/history-noslash/-/history-noslash-5.2.0-noslash.2.0.tgz#52641d588bad50f470463a9ea727a896ebf6a57d"
integrity sha512-sabmZ4x3afCjkzhB8QXJVg4gmgPLAW7e2uPbbEJ1ogs7oASH2dtbAs5IZAP7zGqJTVve5PIfey6q0Kofi8Y7qA==
dependencies:
"@babel/runtime" "^7.7.6"

Expand Down