DEV Community

loading...

Using Children Props for Authenticated Routing in React Router v5 and React 16.9

gloriamaris profile image Monique Dingding ・2 min read

One of the universal pains of all SPA developers is to control the access of some pages only to the authenticated users.

For example, landing pages = good. Pages inside the dashboard = no bueno.

My solution is to exploit React's special children props and build a wrapper component around the routes I want controlled access from.

What is a children prop?

Essentially, everything inside an opening and closing tag of a component is the children of that component. This is usually helpful in building Layout components, (if you use that design pattern, which you should).

Routes.js

In a very v3 fashion (hehe), I have a Routes file which contains a list of all the routes available in the application.

import App from './components/App'
import Login from './components/Login'
import Messages from './components/Messages'
import Settings from './components/Settings'
import { routes } from './routes-list' // just a list of paths

export default Routes = () => {
    return (
        <Router>
            <Switch>
                <Route exact path="/" component={App}/>
                <Route exact path={routes.login} component={Login}/>

               // Private routes
                <Route exact path={routes.messages} component={Messages}/>
                <Route exact path={routes.settings} component={Settings}/>
            </Switch>
        </Router>
    )
}

Enter fullscreen mode Exit fullscreen mode

New Component: PrivateRoute

PrivateRoute serves as a wrapper component to all of the routes that need authentication. Authentication method is highly specific to an application so you may want to use or create your own, but essentially, it should check if the user is allowed access to these private routes. Otherwise, the app redirects to /login page.

import React, { Fragment } from 'react'
import { Redirect } from 'react-router-dom'
import { isUserAuthenticated } from './utils/auth'

export default PrivateRoute = (props) => (
    <Fragment>
        { isUserAuthenticated() ? props.children : <Redirect to={routes.login} /> }
    </Fragment>
)

Enter fullscreen mode Exit fullscreen mode

Implementation

Inside Routes.js, wrap the routes you need to make private.

// ...all the imports
import PrivateRoute from './components/PrivateRoute'

export default Routes = () => {
    return (
        <Router>
            <Switch>
                <Route exact path="/" component={App}/>
                <Route exact path={routes.login} component={Login}/>

               // Private routes
                <PrivateRoute>
                    <Route exact path={routes.messages} component={Messages}/>
                    <Route exact path={routes.settings} component={Settings}/>
                </PrivateRoute>
            </Switch>
        </Router>
    )
}

Enter fullscreen mode Exit fullscreen mode

That's about it!

If you are interested in knowing other implementations of authenticated routing in React (and trust me, there are lots), I have compiled here a curated list as a guide:

As always, happy coding!

Discussion

pic
Editor guide
Collapse
ssaric profile image
Sanjin Šarić

Very elegant.