React-router: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 214: Line 214:


export default withRouter(CompWithProps);
export default withRouter(CompWithProps);
</syntaxhighlight>
==Router with Parameter==
When using REST API we usually have /v1/api/order/:id. To implement this with React Router v4 we create a component to extract the parameter
<syntaxhighlight lang="JavaScript">
</syntaxhighlight>
</syntaxhighlight>



Revision as of 11:10, 6 July 2021

Introduction

This page is about routering with React.

Setup

Install package for Router

npm i react-router-dom

Add BrowserRouter to Index.js

...
import { BrowserRouter } from 'react-router-dom';
...
ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);

Add Routes to App.js

We need to a routes to the the router we support.

import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';

import Explore from './components/Explore';
import Home from './components/Home';
import Messages from './components/Messages';
import Profile from './components/Profile';

function App() {
  return (

    <Router>
        <div>
          <h2>Welcome to React Router Tutorial</h2>
          <nav className="navbar navbar-expand-lg navbar-light bg-light">
          <ul className="navbar-nav mr-auto">
            <li><Link to={'/'} className="nav-link"> Home </Link></li>
            <li><Link to={'/explore'} className="nav-link">Explore</Link></li>
            <li><Link to={'/messages'} className="nav-link">Messages</Link></li>
            <li><Link to={'/profile'} className="nav-link">Profile</Link></li>
          </ul>
          </nav>
          <hr />
          <Switch>
              <Route exact path='/' component={Home} />
              <Route path='/explore' component={Explore} />
              <Route path='/messages' component={Messages} />
              <Route path='/profile' component={Profile} />
          </Switch>
        </div>
      </Router>

  );
}

export default App;

Create Pages

Functional Based

Create a component for each page

import React from 'react'

const Home = () => {
  return (
    <div>
        <h2>Home</h2>
    </div>
  );
};
export default Home

Class Component Based

Create a component for each page

import React, { Component } from 'react';

class Profile extends Component {
  render() {
    return (
        <div>
          <h2>Profile</h2>
        </div>
    );
  }
}
export default Profile;

Component Based

NavLink Component

This allows us to work with the activeClassName and exact to highlight the list which is active.

  <Router>
    <Nav authenticated={!defaultToSignIn} />
    <hr />
    <Switch>
      <Route path="/" component={Home} exact />
      <Route path="/auth/login" component={Login} />
      <Route path="/auth/Register" component={Register} />
      <Route path="/auth/logout" component={Logout} />
    </Switch>
  </Router>

And for some of the NavLink routes

            <li className="nav-item">
              <NavLink
                to="/home"
                aria-current="page"
                className="nav-link"
                exact
              >
                Home
              </NavLink>
            </li>
        </ul>
        <ul className="navbar-nav ms-auto mb-2 mb-lg-0">
            <li className="nav-item">
              <NavLink to="/explore" aria-current="page" className="nav-link">
                Explore
              </NavLink>
            </li>
            <li className="nav-item">
              <NavLink to="/messages" aria-current="page" className="nav-link">
                Messages
              </NavLink>
            </li>

Prompt Component

We can prevent leaving of a page with the Prompt component. For example.

...
  return (
    <div className="Login">
      {error && <p intent="danger">{error}</p>}
      <Prompt
        when={!usernameValid || !passwordValid}
        message="Leaving page will loose your data"
      />
      <Form onSubmit={handleSubmit} className="row g-3 needs-validation">
        <div>
          <div className="col-md-4">
            <Form.Group size="lg" controlId="username">
              <Form.Label>Username</Form.Label>
              <Form.Control
...

Adding a 404 Page

To implement this we just create a route with no path and a component

  <Router>
    <Nav authenticated={!defaultToSignIn} />
    <hr />
    <Switch>
      <Route
        exact
        path="/"
        render={() =>
          defaultToSignIn ? (
            <Redirect to="/auth/login" />
          ) : (
            <Redirect to="/home" />
          )
        }
      />
      <ProtectedRoute path="/" component={Home} exact />
      <ProtectedRoute path="/explore" component={Explore} />
      <ProtectedRoute path="/messages" component={Messages} />
      <ProtectedRoute path="/profile" component={Profile} />
      <Route path="/auth/login" component={Login} />
      <Route path="/auth/Register" component={Register} />
      <Route path="/auth/logout" component={Logout} />
      <Route component={PageNotFound} />
    </Switch>
  </Router>

Rendering Component with Parameters

When you need to add props to the component to render we use the render property which takes a function as an argument and should return the Component for the page.

Router

  <Router>
    <Switch>
      <Route path="/auth/logout" component={Logout} />
      <Route path="/compwithprops" render={() => {
           return <CompWithProps prop1="#ff0000" prop2='Red'/>
      }) />
      <Route component={PageNotFound} />
    </Switch>

Component

For the component we need to wrap it with withRouter in a HOC.

import React from "react";

const CompWithProps = ({prop1,prop2}) => (
  <div>
..
  </div>
);

CompWithProps.proptypes = {
    prop1: PropTypes.string.isRequired,
    prop2: PropTypes.string.isRequired,
}

export default withRouter(CompWithProps);

Router with Parameter

When using REST API we usually have /v1/api/order/:id. To implement this with React Router v4 we create a component to extract the parameter

Router Children Component

All router children components get the following props.

  • match Exact Match, Params, Path and matching Url
  • location Key, path name and search
  • history This is the browser history

Transitions

You need to provide a class prefix in this case trans.

import {TransitionGroup, CSSTransition} from 'react-transition-group'

<TransactionGroup>
  <CSSTransition key={location.key} classNames={'trans'} timeout={1000}>
    <Switch location={location}>
     <Route path={`${match.url}`} component={LoremNumber} exact/>
     <Route path={`${match.url}/:id`} component={LoremNumber} exact/>
    </Switch>
</TransactionGroup>

And the CSS

.trans-enter {
   opacity: 0;
   z-index: 1;
}

.trans-exit {
   display: none
}

.trans-enter.trans-enter-active {
   opacity: 1;
   transition: opacity 1000ms ease-in;
}