Guest User

Untitled

a guest
May 21st, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.24 KB | None | 0 0
  1. Basic react-router 4 setup for login and protected routes.
  2.  
  3. Assuming there is a `UserStore` that can perform the actual operations. It also provides a `user` prop to pages when the user is logged in.
  4.  
  5. Omitting any insiginificant import statements. This is not copy-pastable code, but still real-world code. (Omitted some project/ui-specific stuff)
  6.  
  7. ## index.js
  8.  
  9. Renders the `App`, but wrapped in a `Router`. That way we can use `Route` and `Switch` components anywhere in our app tree.
  10.  
  11. ```
  12. import { Router } from 'react-router-dom';
  13. import App from './App';
  14.  
  15. ReactDOM.render(
  16. <Router>
  17. <App />
  18. </Router>,
  19. document.getElementById('root')
  20. );
  21. ```
  22.  
  23. ## App.js
  24.  
  25. Defines the "outline" of our app - a mapping of routes and components.
  26. Note how we use the regular `Route` and the custom `ProtectedRoute`.
  27.  
  28. ```
  29. import { Route, Switch } from 'react-router-dom';
  30. import ProtectedRoute from './ProtectedRoute';
  31.  
  32. export default class App extends Component {
  33. render() {
  34. return (
  35. <div className={cx('App', css.App)}>
  36. <Switch>
  37. <Route exact path="/login" component={LoginPage} />
  38.  
  39. <ProtectedRoute exact path="/" component={DashboardPage} />
  40. <ProtectedRoute exact path="/dashboard" component={DashboardPage} />
  41. <ProtectedRoute path="/concept/:conceptID?/:selectedID?" component={ConceptPage} />
  42. <ProtectedRoute path="/settings" component={SettingsPage} />
  43. </Switch>
  44. </div>
  45. );
  46. }
  47. }
  48. ```
  49.  
  50. ## ProtectedRoute.js
  51.  
  52. A special route that will redirect to `/login` unless already logged in.
  53.  
  54. Note how it expects to receive a `user` prop to know whether it's logged in or not.
  55. In this example, it uses a decorator to retrieve the value from a store. The `user` value will be either undefined or an object.
  56. We use the `render` prop of `Route` and decide what to render based the `user` value.
  57.  
  58. ```
  59. import { Route, Redirect } from 'react-router-dom';
  60.  
  61. @connect([
  62. {
  63. store: UserStore,
  64. props: ['user']
  65. }
  66. ])
  67. export default class ProtectedRoute extends PureComponent {
  68. static propTypes = {
  69. user: PropTypes.object,
  70. component: PropTypes.oneOfType([PropTypes.node, PropTypes.element, PropTypes.func])
  71. };
  72. render() {
  73. const { user, component: Component, ...props } = this.props;
  74. return (
  75. <Route
  76. {...props}
  77. render={props => {
  78. if (user) {
  79. return <Component {...props} />;
  80. } else {
  81. return <Redirect to="/login" />;
  82. }
  83. }}
  84. />
  85. );
  86. }
  87. }
  88. ```
  89.  
  90. ## LoginPage.js
  91.  
  92. Displays a login form, keeps user input in its state and finally submits it.
  93. Notice how it expects the `location` and retrieves it using `export default withRouter()`.
  94.  
  95. It uses the `UserStore.login()` method, which will eventually cause the `user` prop to become populated.
  96. That will cause a re-render which will redirect to the originally requested page..
  97.  
  98. ```
  99. import { Redirect, withRouter, Link } from 'react-router-dom';
  100.  
  101. @connect([
  102. {
  103. store: UserStore,
  104. props: ['user']
  105. }
  106. ])
  107. class LoginPage extends Component {
  108. static propTypes = {
  109. user: PropTypes.object,
  110. location: PropTypes.shape({
  111. state: PropTypes.shape({
  112. from: PropTypes.string
  113. })
  114. })
  115. };
  116. state = {
  117. username: '',
  118. password: ''
  119. };
  120. render() {
  121. const { user } = this.props;
  122. const { username, password } = this.state;
  123. const { from } = this.props.location.state || { from: { pathname: '/' } };
  124. if (user) {
  125. return <Redirect to={from} />;
  126. }
  127. return (
  128. <div className={cx('Page LoginPage', css.LoginPage)}>
  129. <h3>Login</h3>
  130. <form onSubmit={this.handleSubmit}>
  131. <div>
  132. <label>Username</label>
  133. <input
  134. type="text"
  135. value={username}
  136. onChange={e => this.setState({ username: e.target.value })}
  137. />
  138. </div>
  139. <div>
  140. <label>Password</label>
  141. <input
  142. type="password"
  143. value={password}
  144. onChange={e => this.setState({ password: e.target.value })}
  145. />
  146. </div>
  147. <footer>
  148. <Link to="/register">Register</Link>
  149. <Button onClick={this.handleSubmit} type="submit" disabled={!username || !password}>
  150. Login
  151. </Button>
  152. </footer>
  153. </form>
  154. </div>
  155. );
  156. }
  157. @autobind
  158. handleSubmit(e) {
  159. e.preventDefault();
  160. e.stopPropagation();
  161. this.login();
  162. }
  163. @autobind
  164. login() {
  165. const { username, password } = this.state;
  166. if (!username || !password) return;
  167. UserStore.login({ username, password });
  168. }
  169. }
  170. export default withRouter(LoginPage);
  171. ```
Add Comment
Please, Sign In to add comment