read24 - Admin UI: Navigation Bar

August 02, 2020

Roger Ngo

I would like to make more pages than what I have currently. So before I continue on making the AddBook form better by including more form validation, etc… I’d like to get rid of a peeve of mine and address the issue in not having a navigation bar at the top of the page so that I can navigate to other pages for testing in the future.

The Twitter Bootstrap NavBar component seems pretty cool to me: https://getbootstrap.com/docs/4.5/components/navbar/.

It has everything I need, and I will use that.

Okay let’s make a new file. I think I will name it Navigation.tsx. It should be created under components in the admin project. Then I’ll just create some stub content, and mount the component at the top of every page. This means that I will add the rendering of the component in the index.tsx file.

import React from 'react';

export default function Navigation() {
    return <div>Hello</div>;
}

And then:

ReactDOM.render(
  <React.StrictMode>
    <div className="container">
      <div className="row">
        <div className="col col-12">
          <Navigation />
        </div>
      </div>
      <div className="row">
        <Home />
      </div>
    </div>
  </React.StrictMode>,
  document.getElementById('root')
);

Which gives me:

Mounting the test Navigation component

Awww yeah, baby steps… confidence. Now time to give it some purpose. I will just create a basic styled navigation bar with just two links: Home, and Add Book. Of course with Add Book, I can use the page I have made so far, but for Home, let’s actually create a proper page for that.

import React from 'react';
import './Navigation.css';

export default function Navigation() {
    return (
        <div>
            <nav className="navbar navbar-expand-lg navbar-light">
                <a className="navbar-brand" href="#">read24</a>
                <div className="navbar-nav">
                    <a className="nav-item nav-link" href="#">Home</a>
                    <a className="nav-item nav-link" href="#">Add Book</a>
                </div>
            </nav>
        </div>
    );
}

I think the home page can be simple right now. It can just be a greeting.

import React from 'react';

export default function Home() {
    return (
        <div className="container">
            <div className="row">
                <div className="col col-12">
                    Let's make it a great day.
                </div>
            </div>
        </div>
    );
}
Rendered Navigation component

Looks pretty good!

Now I actually have two different pages. But how do I make the navigation bar navigate to them? I guess this is where react-router will come into play.

npm install --save react-router-dom
npm install --save-dev @types/react-router-dom

Now, just import BrowserRouter, Route, Switch into index.tsx, and rewrite the component to render the pages depending on the URL match:‌

ReactDOM.render(
  <React.StrictMode>
    <Router>
      <div className="container">
        <div className="row">
          <div className="col col-12">
            <Navigation />
          </div>
        </div>
        <div className="row">
          <Switch>
            <Route exact path="/">
              <Home />
            </Route>
            <Route path="/book/add">
              <AddBook />
            </Route>
          </Switch>
        </div>
      </div>
    </Router>
  </React.StrictMode>,
  document.getElementById('root')
);

The Navigation component will render out Link components which then will change the current URL, and have the Switch match against the child Route components.

import React from 'react';
import { Link } from 'react-router-dom';

import './Navigation.css';

export default function Navigation() {
    return (
        <div>
            <nav className="navbar navbar-expand-lg navbar-light">
                <a className="navbar-brand" href="#">read24</a>
                <div className="navbar-nav">
                    <Link to="/" className="nav-item nav-link">Home</Link>
                    <Link to="/book/add" className="nav-item nav-link">Add Book</Link>
                </div>
            </nav>
        </div>
    );
}
Testing Navigation component