Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow an array of strings in <Route path> #5866

Closed
mjackson opened this issue Jan 12, 2018 · 9 comments
Closed

Allow an array of strings in <Route path> #5866

mjackson opened this issue Jan 12, 2018 · 9 comments

Comments

@mjackson
Copy link
Member

This is a follow-up from #5393.

It would be nice if <Route path> could accept an array of strings instead of a single string. This would make it possible to render the same <Route> element at multiple different URLs as suggested here.

The reason #5393 was not merged is because there was a problem with the way the code worked with respect to relative routes. When this work is done, match.path should still be a string, not an array.

@Fi1osof
Copy link

Fi1osof commented Apr 2, 2018

Thanks! Its work. But i got warning Failed prop type: Invalid prop pathof typearraysupplied toRoute, expected string`.

@o-mega
Copy link

o-mega commented Apr 2, 2018

It works but not as expected.
There is no props.match.params data for each path in an array.

@crobinson42
Copy link

Working great, just throwing the propTypes warning mentioned above 👍

@kyleramirez
Copy link

kyleramirez commented Apr 28, 2018

What needs to be done to remove this prop-types warning?

In the meantime, I patch this in my own codebase by overriding the default prop types.

For those of you reading this, here is what I do:

import { Route } from "react-router-dom"
import PropTypes from "prop-types"

Route.propTypes = {
  computedMatch: PropTypes.object,
  path: PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
  exact: PropTypes.bool,
  strict: PropTypes.bool,
  sensitive: PropTypes.bool,
  component: PropTypes.func,
  render: PropTypes.func,
  children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
  location: PropTypes.object
}

@dorrogeray
Copy link

Hi,

there seems to be an issue with match.params when defining multiple paths for one route with same named params.

Example, using following paths:

const paths = [
	'/:mutation(cs)',
	'/:mutation(cs)-:currency(czk|eur)',
]

Url /cs will have match.params.mutation undefined. It clearly gets overwritten by the 'non matched' mutation from the second path, which is not matched.

This is likely comes from the way pathToRegexp works.

let keys = [];
pathToRegexp(paths, keys);

Will set keys to:

[
  {
    "name": "mutation",
    "prefix": "/",
    "delimiter": "/",
    "optional": false,
    "repeat": false,
    "partial": false,
    "asterisk": false,
    "pattern": "cs"
  },
  {
    "name": "mutation",
    "prefix": "/",
    "delimiter": "/",
    "optional": false,
    "repeat": false,
    "partial": true,
    "asterisk": false,
    "pattern": "cs"
  },
  {
    "name": "currency",
    "prefix": "",
    "delimiter": "/",
    "optional": false,
    "repeat": false,
    "partial": false,
    "asterisk": false,
    "pattern": "czk|eur"
  }
]

The workaround is to name the param in first path differently, and then resolve the params manually.

const paths = [
	'/:mutationA(cs)',
	'/:mutationB(cs)-:currency(czk|eur)',
]

Using version 4.2.2.

@maxparelius
Copy link

Getting same issue as @dorrogeray in one of my projects. The workaround to have different named params for each route is not great. What is the status on this PR? This is highly needed and makes sense to have as it aligns with pathToRegexp expected behavior. When will this go live?

@acro5piano
Copy link

acro5piano commented Aug 15, 2018

It would be really happy if this feature will be added, but for now I found a solution for my use case.

I made a parameter optional, for use cases like:

  • Route has common path such as /users and /users/create
  • Want to mount once for those compnents

before:

<Route exact path="/users" component={UserList} />
<Route exact path="/users/create" component={UserList>} />

after:

<Route exact path="/users/:action?" component={UserList>} />

before renders twice while after renders once.

Furthermore, UserList.props should be like this:

{
    match: {
        params: {
            action: undefined | string
        }
    }
}

refs:

@iamdanthedev
Copy link

iamdanthedev commented Aug 27, 2018

declare module "react-router" {
  import { RouteProps as RoutePropsOrig } from "@types/react-router";
  import * as React from "react";
  export * from "@types/react-router";

  export type RouteProps = Omit<RoutePropsOrig, "path"> & {
    path: string[] | string;
  };

  export class Route extends React.Component<RouteProps, any> {}
}
// @ts-ignore
Route.propTypes.path = any;

solves the problem :-)

@mjackson
Copy link
Member Author

Closed by #5889.

@lock lock bot locked as resolved and limited conversation to collaborators Dec 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants