How to protect your routes with React Context

paul christophe
Apr 19, 2018 · 5 min read

What is Context?

Isn’t that what Redux is for?

Basic Concepts

Let’s Start Building

Context Header

/* AuthContext.js */import React from 'react';const AuthContext = React.createContext();
/* AuthContext.js */...class AuthProvider extends React.Component {
state = { isAuth: false }
render() {
return (
<AuthContext.Provider
value={{ isAuth: this.state.isAuth }}
>
{this.props.children}
</AuthContext.Provider>
)
}
}
const AuthConsumer = AuthContext.Consumerexport { AuthProvider, AuthConsumer }
/* index.js */
import React from 'react';
import { render } from 'react-dom';
import { AuthProvider } from './AuthContext';
import Header from './Header';
const App = () => (
<div>
<AuthProvider>
<Header />
</AuthProvider>
</div>
);
render(<App />, document.getElementById('root'));
/* Header.js */
import React from 'react'
import { AuthConsumer } from './AuthContext'
import { Link } from 'react-router-dom'
export default () => (
<header>
<AuthConsumer>

</AuthConsumer>
</header>
)
/* Header.js */
...
export default () => (
<header>
<AuthConsumer>
{({ isAuth }) => (
<div>
<h3>
<Link to="/">
HOME
</Link>
</h3>
{isAuth ? (
<ul>
<Link to="/dashboard">
Dashboard
</Link>
<button>
logout
</button>
</ul>
) : (
<button>login</button>
)}
</div>
)}
</AuthConsumer>
</header>
)
/* AuthContext.js */
...
class AuthProvider extends React.Component {
state = { isAuth: false }
constructor() {
super()
this.login = this.login.bind(this)
this.logout = this.logout.bind(this)
}
login() {
// setting timeout to mimic an async login
setTimeout(() => this.setState({ isAuth: true }), 1000)
}
logout() {
this.setState({ isAuth: false })
}
render() {
return (
<AuthContext.Provider
value={{
isAuth: this.state.isAuth,
login: this.login,
logout: this.logout

}}
>
{this.props.children}
</AuthContext.Provider>
)
}
}
/* Header.js */
...
export default () => (
<header>
<AuthConsumer>
{({ isAuth, login, logout }) => (
<div>
<h3>
<Link to="/">
HOME
</Link>
</h3>
{isAuth ? (
<ul>
<Link to="/dashboard">
Dashboard
</Link>
<button onClick={logout}>
logout
</button>
</ul>
) : (
<button onClick={login}>login</button>
)}
</div>
)}
</AuthConsumer>
</header>
)

Protected Route With Context

/* Dashboard.js */
import React from 'react'
const Dashboard = () => <h2>User Dashboard</h2>export default Dashboard
/* index.js */
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { AuthProvider } from './AuthContext';
import Landing from './Landing';
import Dashboard from './Dashboard';

import Header from './Header';
const App = () => (
<div>
<Router>
<AuthProvider>
<Header />
<Switch>
<Route path="/dashboard" component={Dashboard} />
<Route path="/" component={Landing} />
</Switch>

</AuthProvider>
</Router>
</div>
);
render(<App />, document.getElementById('root'));
/* ProtectedRoute.js */
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { AuthConsumer } from './AuthContext';
const ProtectedRoute = () => (
<AuthConsumer>
{({ isAuth }) => (
)}
</AuthConsumer>
);
export default ProtectedRoute;
const ProtectedRoute = ({ component: Component, ...rest }) => (
const ProtectedRoute = ({ component: Component, ...rest }) => (
<AuthConsumer>
{({ isAuth }) => (
<Route
render={
props =>
isAuth
? <Component {...props} />
: <Redirect to="/" />
}
{...rest}
/>

)}
</AuthConsumer>
)
/* index.js */
...
<ProtectedRoute path="/dashboard" component={Dashboard} />

freeCodeCamp.org

This is no longer updated. Go to https://freecodecamp.org/news instead

Thanks to averymax.

paul christophe

Written by

http://bit.ly/extensionfocus // neondaylight.com

freeCodeCamp.org

This is no longer updated. Go to https://freecodecamp.org/news instead