loading...
Cover image for Demystifying 7 lesser-known React Router terms and features (With examples) ๐Ÿ”ฎ

Demystifying 7 lesser-known React Router terms and features (With examples) ๐Ÿ”ฎ

vaibhavkhulbe profile image Vaibhav Khulbe ใƒป5 min read

Previously, we talked about some of the major terms or features of React-Redux which may go unnoticed as we build or work on more and more project with the awesome UI library.

This time though, I'm putting a few essential terms in the form of questions for React Router. As you may know, it's a powerful routing library which helps to add new screens (pages) in your app quickly all while keeping the URL in sync with what's being displayed on the page.

Of course, just like before, there will be definite examples for each of them!


Mystery GIF

Let's demystify!

1. How React Router differs from the history library? (Doc ๐Ÿ“ƒ) (โ—Ž๏นโ—Ž)

You already know what React Router is, but what is this history library and how is it different?

The history library lets you easily manage session history anywhere JavaScript runs. It abstracts away the differences in various environments and provides a minimal API that lets you manage the history stack, navigate, and persist state between sessions.

As for, React Router, it is a wrapper around history which handles interaction with the browser's window.history API with its browser and hash histories.

2. What is the purpose of push() and replace() methods of history? ใค๏นโŠ‚

> push() (Doc ๐Ÿ“ƒ)

The push(path, [state]) method pushes a new entry onto the history stack.

Example:

// usually all you need
<Link to="/somewhere"/>

// but you can use a location instead
const location = {
  pathname: '/somewhere',
  state: { fromDashboard: true }
}

<Link to={location}/>
<Redirect to={location}/>
history.push(location)

> replace() (Doc ๐Ÿ“ƒ)

The replace(path, [state]) method replaces the current entry on the history stack.

Example:

// Continued from the above example

<Link to={location}/>
<Redirect to={location}/>
history.push(location)
history.replace(location)

3. How to get query parameters in React Router v4? โ•ฎ๏ผˆโ•ฏ๏ผฟโ•ฐ๏ผ‰โ•ญ

Of course, you use the Polyfill library for old browser support but there is a recommended way to do this with the help of query-string library. Here's how:

const queryString = require('query-string');
const parsed = queryString.parse(props.location.search);

Another way can be to use the native URLSearchParams interface. Check out the following example:

const params = new URLSearchParams(props.location.search)
const foo = params.get('name')

4. How to solve the "A Router may have only one child element" warning? ใ„Ÿ( โ–”, โ–” )ใ„

As per its source code, the Router expects this.props.children to be null. So, you have to wrap all of your <Route /> statements inside a <Switch> which renders a route exclusively. Here's the complete solution to this:

// Add the `Switch` import:
import { Switch, Router, Route } from 'react-router'

// Enclose all your routes inside this new `<Switch>` block:
<Router>
  <Switch>
    <Route {/* ... */} />
    <Route {/* ... */} />
  </Switch>
</Router>

For a detailed discussion check out the following question on Stackoverflow:

React-Router only one child

70

I keep on getting the error:

A 'Router' may have only one child element

when using react-router.

I can't seem to figure out why this is not working, since it's exactly like the code they show in their example: Quick Start

Here is my code:

import React from 'react';
import
โ€ฆ

5. How to pass params to history.push() in React Router v4? ยฏ(ยฐ_o)/ยฏ

The history.push() method will push a new entry onto the history stack. While you implement navigation, you can pass the params required in the following fashion:

this.props.history.push({
  pathname: '/template',
  search: '?query=abc', // Here
  state: { detail: response.data }
})

6. How do you implement a default or PageNotFound page? (ยฐใƒผยฐใ€ƒ)

Again, the <Switch> component will help you here. As per the documentation:

A <Switch> renders the first child <Route> that matches. A <Route> with no path always matches.

Example:

<Router>
  <div>
    <Switch>
      <Route path="/" exact component={Home}/>
      <Redirect from="/old-match" to="/will-match"/>
      <Route path="/will-match" component={WillMatch}/>
      <Route component={NoMatch}/>
    </Switch>
  </div>
</Router>

All you need to do is add a path with <Switch> as follows:

<Switch>
  <Route exact path="/" component={Home}/>
  <Route path="/user" component={User}/>
  <Route component={Notfound} /> 
</Switch

React Router documentation has an example regarding this embedded below from CodeSandbox:

Edit React Router - No Match (404)

7. How do you add the automatic redirect feature after login? (o_ _)๏พ‰

You can use the <Redirect> component. Rendering a <Redirect> will navigate to a new location. The new location will override the current location in the history stack.

import { Redirect } from 'react-router'

export default class LoginComponent extends Component {
  render() {
    if (this.state.isLoggedIn === true) {
      return <Redirect to="/your/redirect/page" />
    } else {
      return <div>{'Login Please'}</div>
    }
  }
}

Watch this video from this Scotch.io course on how to implement Redirect with authentication.


So, how was it? Did you find something cool? I've never implemented authentication with React Router by will definitely try it soon. What more terms or features can you demystify? The comment box is all yours!


๐Ÿ“ซ Subscribe to my weekly developer newsletter ๐Ÿ“ซ

PS: From this year, I've decided to write here on DEV Community. Previously, I wrote on Medium. If anyone wants to take a look at my articles, here's my Medium profile.

Discussion

pic
Editor guide