< Previous: Creating a Link Between Pages in React Router   Next: Adding a Root Route Using React Router and IndexRoute >

Making Custom URLs with React Router Params

So far we've been working with the React repository on GitHub, but now it's time we started using different repositories as well. Specifically, we want users to be able to choose between React, React Native and Jest in the List component, then load the correct Detail component for each of those.

We currently have these two routes defined in index.js:

src/index.js

<Route path="/" component={ List } />
<Route path="/react" component={ Detail } />

You might very well think we just need to extend that like so:

<Route path="/" component={ List } />
<Route path="/react" component={ Detail } />
<Route path="/react-native" component={ Detail } />
<Route path="/jest" component={ Detail } />

That's certainly a possibility, but it's neither flexible or scalable. Wouldn't it be much better if we could write any link like /detail/??? and have our Detail component figure out what that means? Sure it would. And fortunately React Router makes it easy – in fact it's just a matter of rewriting your routes to this:

src/index.js

<Route path="/" component={ List } />
<Route path="/detail/:repo" component={ Detail } />

Yes, that's it. Just by writing :repo in the URL, React Router will automatically pull out whatever text comes in that part of the URL, then pass it to the Detail component to act on. Sure, we still need to actually do something with the repository name, but it means the Detail component will now work for /detail/react, /detail/react-native and so on.

Given how easy that step was, you're probably imagining there's lots of work to do in the Detail component. Well, you'd be wrong: we have to change just one part of one line in order to make it work. Isn't React Router clever?

In Detail.js look for this line inside the fetchFeed() method:

src/pages/Detail.js

ajax.get(`https://api.github.com/repos/facebook/react/${type}`)

If you remember, that uses ES6 string interpolation so that the URL gets written as .../react/commits, .../react/pulls, etc. Thanks to the magic of React Router, we can use the exact same technique with the name of the repository too. We used :repo inside our route, and React Router will automatically make that available to the Detail component as this.props.params.repo.

So, replace that existing ajax.get() call with this:

src/pages/Detail.js

const baseURL = 'https://api.github.com/repos/facebook';
ajax.get(`${baseURL}/${this.props.params.repo}/${type}`)

That now does a triple interpolation: once for the :repo part of our URL, and again for the view mode that's currently selected, i.e. commits, forks and pulls. I added a third one for baseURL to avoid the line getting too long to read easily.

The final step is to modify List.js so that it points to more than one repository. Update its render() method to this:

src/pages/List.js

render() {
    return (
        <div>
            <p>Please choose a repository from the list below.</p>
            <ul>
                <li><Link to="/detail/react">React</Link></li>
                <li><Link to="/detail/react-native">React Native</Link></li>
                <li><Link to="/detail/jest">Jest</Link></li>
            </ul>
        </div>
    );
}

Now save all your work, and go to http://localhost:8080/ in your browser. You should see three links to choose from, each showing different GitHub repositories. You should also be able to use your browser's back button to return to the list and choose a different repository.

The new List page shows multiple repositories for the user to choose from, and all three point to the same Detail page.

Buy the book for $10

Get the complete, unabridged Hacking with React e-book and take your learning to the next level - includes a 45-day no questions asked money back guarantee!

If this was helpful, please take a moment to tell others about Hacking with React by tweeting about it!

< Previous: Creating a Link Between Pages in React Router   Next: Adding a Root Route Using React Router and IndexRoute >

Copyright ©2016 Paul Hudson. Follow me: @twostraws.