20

I have a legacy web app that is being replaced with React and it is called by these various systems by being passed a URL (derived from records in and existing DB system) The app renders folder views, of files in a sandboxed container according to the path passed in.

I need to be able to identify these requests and route them to a File/Folder handing page, treating everything after the '/files/ part of the path down as a parameter to the path of the file or folder.

<Route path="/" handler={Master}>
  <Route name="files_link" path="files" handler={Files} />
  <Route name="filesWithPath_link" path="files/*:path" handler={Files} />
</Route>

I would like to be able to handle requests passed into

/files  

and have it handled in the page (defaulting to top level folder because no path parameter passed.

and have all the following examples of possible URL just passed to the router and extract the path parameter from the bit after /files/.

/files/folder                                 path=folder
/files/folder/filename.ext                    path=folder/filename.ext
/files/folder/folder1                         path=folder/folder1
/files/folder/folder1/filename.ext            path=folder/folder1/filename.ext
/files/folder/folder1/folder2/                path=folder/folder1/folder2
/files/folder/folder1/folder2/filename.ext    path=folder/folder1/folder2/filename.ext

.... and so on ...

When I try this I get an error

Uncaught Invariant Violation: Missing "splat" parameter for path "/beta/page/files/*:path"

I'm currently using react 0.14.2 and react-router 0.13.4.

How would you go about handling a variable length path in this manner in React-router?

laser
  • 1,388
  • 13
  • 14
Code Uniquely
  • 6,356
  • 4
  • 30
  • 40

4 Answers4

38

You need to use it like so:

<Route name="filesWithPath_link" path="files/*" handler={Files} />

And then in your React component you can access the value of the splat:

    // The '*' in the path match gets assigned to this.props.params.splat
    var path = this.props.params.splat;
Jamis Charles
  • 5,827
  • 8
  • 32
  • 42
3

For completeness, the splat parameter can be accessed from the useParams() hook as property 0:

const splat = useParams()[0];
Lukas Bach
  • 3,559
  • 2
  • 27
  • 31
1

In React Router v6, the "*" can be accessed from useParams() as a property named *.

const wildcard = useParams()["*"];

And of course you can always get the entire URL (i.e. everything including the bit before the *) using useLocation()

HughHughTeotl
  • 5,439
  • 3
  • 34
  • 49
-1

Example in TypeScript with a named parameter:

<Route path="/files/:path">
  <Files/>
</Route>


import { useParams } from 'react-router';

export function Files(): React.ReactElement {
  const splat = useParams<{ path: string }>().path;
}
Christopher K.
  • 1,015
  • 12
  • 18