Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # react-router 4 basic setup
- Basic react-router 4 setup for login and protected routes.
- Requires the user to log in in order to see those protected routes.
- * Assuming there is a `UserStore` that performs actual operations (e.g. ajax calls) and provides a `user` prop to components when the user is logged in.
- * Omitting any insiginificant import statements. This is not 100% copy-pastable, but still pretty much real-world code
- ## index.js
- Renders the `App`, but wrapped in a `Router`. That way we can use `Route` and `Switch` components anywhere in our app tree.
- ```
- import { Router } from 'react-router-dom';
- import App from './App';
- ReactDOM.render(
- <Router>
- <App />
- </Router>,
- document.getElementById('root')
- );
- ```
- ## App.js
- Defines the "outline" of our app - a mapping of routes and components.
- Note how we use the regular `Route` and the custom `ProtectedRoute`.
- ```
- import { Route, Switch } from 'react-router-dom';
- import ProtectedRoute from './ProtectedRoute';
- export default class App extends Component {
- render() {
- return (
- <div className={cx('App', css.App)}>
- <Switch>
- <Route path="/login" component={LoginPage} />
- <ProtectedRoute exact path="/" component={DashboardPage} />
- <ProtectedRoute path="/dashboard" component={DashboardPage} />
- <ProtectedRoute path="/concept/:conceptID?/:selectedID?" component={ConceptPage} />
- <ProtectedRoute path="/settings" component={SettingsPage} />
- </Switch>
- </div>
- );
- }
- }
- ```
- ## ProtectedRoute.js
- A special route that will redirect to `/login` unless already logged in.
- Note how it expects to receive a `user` prop to know whether it's logged in or not.
- In this example, it uses a decorator to retrieve the value from a store. The `user` value will be either undefined or an object.
- We use the `render` prop of `Route` and decide what to render based the `user` value.
- ```
- import { Route, Redirect } from 'react-router-dom';
- @connect([
- {
- store: UserStore,
- props: ['user']
- }
- ])
- export default class ProtectedRoute extends PureComponent {
- static propTypes = {
- user: PropTypes.object,
- component: PropTypes.oneOfType([PropTypes.node, PropTypes.element, PropTypes.func])
- };
- render() {
- const { user, component: Component, ...props } = this.props;
- return (
- <Route
- {...props}
- render={props => {
- if (user) {
- return <Component {...props} />;
- } else {
- return <Redirect to="/login" />;
- }
- }}
- />
- );
- }
- }
- ```
- ## LoginPage.js
- Displays a login form, keeps user input in its state and finally submits it.
- Notice how it expects the `location` and retrieves it using `@withRouter` as a decorator (or alternatively `export default withRouter(LoginPage)`).
- It uses the `UserStore.login()` method, which will eventually cause the `user` prop to become populated.
- That will cause a re-render which will redirect to the originally requested page..
- ```
- import { Redirect, withRouter, Link } from 'react-router-dom';
- @withRouter
- @connect([
- {
- store: UserStore,
- props: ['user']
- }
- ])
- export default class LoginPage extends Component {
- static propTypes = {
- user: PropTypes.object,
- location: PropTypes.shape({
- state: PropTypes.shape({
- from: PropTypes.string
- })
- })
- };
- state = {
- username: '',
- password: ''
- };
- render() {
- const { user } = this.props;
- const { username, password } = this.state;
- const { from } = this.props.location.state || { from: { pathname: '/' } };
- if (user) {
- return <Redirect to={from} />;
- }
- return (
- <div className={cx('Page LoginPage', css.LoginPage)}>
- <h3>Login</h3>
- <form onSubmit={this.handleSubmit}>
- <div>
- <label>Username</label>
- <input
- type="text"
- value={username}
- onChange={e => this.setState({ username: e.target.value })}
- />
- </div>
- <div>
- <label>Password</label>
- <input
- type="password"
- value={password}
- onChange={e => this.setState({ password: e.target.value })}
- />
- </div>
- <footer>
- <Link to="/register">Register</Link>
- <Button onClick={this.handleSubmit} type="submit" disabled={!username || !password}>
- Login
- </Button>
- </footer>
- </form>
- </div>
- );
- }
- @autobind
- handleSubmit(e) {
- e.preventDefault();
- e.stopPropagation();
- this.login();
- }
- @autobind
- login() {
- const { username, password } = this.state;
- if (!username || !password) return;
- UserStore.login({ username, password });
- }
- }
- ```
Add Comment
Please, Sign In to add comment