Skip to content

Commit

Permalink
fix: use react-router match route method (#36)
Browse files Browse the repository at this point in the history
* fix: use react-router match route method

This solves a bug where the route matching couldn't find the correct route when the
route was using dynamic parameters (ie: /:something/blue).

* docs: update jsdocs for the find route method
  • Loading branch information
crash7 committed May 29, 2020
1 parent 8c39694 commit 0d51166
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 50 deletions.
52 changes: 7 additions & 45 deletions packages/client/src/Before.component.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,8 @@ import type {
} from 'Before.component';
import React, { useCallback, useEffect, useReducer, useRef, useMemo, memo } from 'react';
import { withRouter, Switch, Route, type ContextRouter } from 'react-router-dom';
import {
compose,
concat,
find,
has,
head,
ifElse,
identity,
last,
propOr,
prop,
propEq,
split,
useWith
} from 'ramda';
import { getQueryString } from './utils';
import { compose, concat, has, head, ifElse, last, propOr, prop, split } from 'ramda';
import { getQueryString, findRouteByPathname } from './utils';

/**
* Extract the base path from given full pathname, for example given the following url `/foo?bar=2`
Expand All @@ -36,12 +22,7 @@ import { getQueryString } from './utils';
* @param {string} pathname the pathname to retrieve the pathname
* @returns {string} the base path
*/
const getBasePath: (pathname: string) => string = compose(
head,
split('#'),
head,
split('?')
);
const getBasePath: (pathname: string) => string = compose(head, split('#'), head, split('?'));

/**
* Extract the search part of a given full pathname or window.Location, for example given the following url `/foo?bar=2`
Expand All @@ -53,28 +34,9 @@ const getBasePath: (pathname: string) => string = compose(
const getSearch: (pathname: string | LocationType) => string = ifElse(
has('search'),
prop('search'),
compose(
concat('?'),
last,
split('?')
)
compose(concat('?'), last, split('?'))
);

/**
* Retrieve the current route by a given path.
* @func
* @param {string} pathname
* @param {array} routes an array of route to filter
* @returs {object|undefined} a valid route
**/
const getRouteByPathname: (path: string, routes: Array<AsyncRoute>) => ?AsyncRoute = useWith(find, [
compose(
propEq('path'),
getBasePath
),
identity
]);

/**
* Generates a random string
* @func
Expand Down Expand Up @@ -156,8 +118,8 @@ export function Before(props: BeforeComponentWithRouterProps) {

const createHistoryMethod = useCallback(
(name: string) => (obj: string | LocationType, state?: { [key: string]: string }) => {
const path: string = propOr(obj, 'pathname', obj);
const route = getRouteByPathname(path, routes);
const path: string = getBasePath(propOr(obj, 'pathname', obj));
const route = findRouteByPathname(path, routes);
if (route) {
const search = getSearch(obj);
fetchInitialProps(
Expand Down Expand Up @@ -194,7 +156,7 @@ export function Before(props: BeforeComponentWithRouterProps) {
interrupt.current = action === 'POP';
if (disableInitialPropsCache || !initialProps.current[location.pathname]) {
// This solves a weird case when, on an advanced step of the flow, the user does a browser back
const route = getRouteByPathname(location.pathname, routes);
const route = findRouteByPathname(location.pathname, routes);
if (route) {
fetchInitialProps(
route,
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/ensureReady.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export async function loadCurrentRoute(
pathname: string = window.location.pathname
) {
let data;
const route = findRouteByPathname(pathname)(routes);
const route = findRouteByPathname(pathname, routes);

if (route) {
const match = matchPath(pathname, route);
Expand Down
11 changes: 7 additions & 4 deletions packages/client/src/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow strict
import { parse } from 'query-string';
import { matchPath } from 'react-router-dom';
import { complement, find, isNil } from 'ramda';
import { complement, find, isNil, curry } from 'ramda';
import type { QueryType } from 'Before.component';
import type { Route } from 'ensureReady';

Expand Down Expand Up @@ -51,8 +51,11 @@ const checkMatchPath = (pathname: string) => (route: Route) => isNotNil(matchPat

/**
* Returns a function that will find a route by a given request pathname.
* @func
* @function
* @param {string} pathname a request pathname
* @returns {function} (routes[]) => route
* @param {Array<Route>} routes a list of routes
* @returns {Route} the route matched with the pathname or undefined
*/
export const findRouteByPathname = (pathname: string) => find(checkMatchPath(pathname));
export const findRouteByPathname = curry((pathname: string, routes: Array<Route>) =>
find(checkMatchPath(pathname), routes)
);

0 comments on commit 0d51166

Please sign in to comment.