Greetings, Friends & Fellow Devs π
I really hope you didn't take the article title for an offense, because if you're pursuing a career (or even a side-hobby) in software engineering, you're most certainly not a dummy, and I have great respect for you. And if you aren't pursuing software engineering, then I highly recommend it, because there are great benefits and we've got jackets.
Not to mention, the original working title was:
<ReactRouterForDummies onRead={changeDummyToSmarty} />
Anyway...
As of the publishing of this article, I am a late-Phase-2 student of Flatiron School's Software Engineering bootcamp, heading into Phase 3. This program is a full-time, intensive, no-nonsense run-through of both front-end and back-end web development technologies. At this point, we have accumulated a comprehensive understanding of the way JavaScript, HTML, and CSS can all work together to render sleek & responsive websites, similar to the one you're seeing at this very moment!
Let's Talk About Frameworks
One way to shape this complex tapestry of web dev languages is through frameworks. A programming framework is:
"...an abstraction in which software [...] can be selectively changed by additional user-written code, thus providing application-specific software. It provides a standard way to build and deploy applications and is a universal, reusable software environment that provides particular functionality as part of a larger software platform to facilitate the development of software applications, products and solutions."ΒΉ
Pretty cool, right?
Frameworks provide a TON of additional efficiencies and functionalities that are a distant fantasy for vanilla (plain) code. And truly, frameworks are the logical next step once you have a solid understanding of the underlying languages & logic beneath them. And that brings us to our topic for this post: The React framework, and more specifically...
React Router
React Router is an extremely capable tool, allowing a React web app to accomplish the goal of client-side routing, which manifests a dynamic website hierarchy based on the content and components within that app. Through React Router, a web developer is able to:
- Easily create a well-organized domain extension hierarchy
- Eliminate the need for a new server request upon navigation between pages within that domain
- Generally boost the speed and clarity of the user experience
Time to Break It Down...
Routers
If you're setting up React Router for use in your web app, you'll need to start by importing your router component itself, in the form of <BrowserRouter> or <HashRouter>. More information on the differences between those here.
Next, you'll need to "wrap your top-level <App/> component" in this router component "at the root of your element hierachy"Β². This should happen in your index.js file, which should look something like this:
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from "react-router-dom"
import './index.css'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
NOTE: You can apply a short name to longer-named imported modules using as, which will clean up your code a bit. You can use whatever short name you want, but it's obviously best to make it relevant. The code above can be made a bit simpler with this tool, importing like so:
import { BrowserRouter as Router } from "react-router-dom";
...and replacing the component labels with that short name.
<Router>
<App />
</Router>
Once you have properly incorporated your Router into your root component, you are then ready to move down a level in your element hierarchy and start building out the Router's functionality in your <App/> component!
Route Matchers
To efficiently create the website's URL hierarchy within the Router, you employ the use of Route Matchers, of which there are two required components: <Switch> and <Route>.
Remember: We have to start by importing both of these components at the beginning of App.js before we can start building them out.
import { Switch, Route } from "react-router-dom"
<Switch> is the parent container component here. It tells our app to read the information within it as Route Matching information. As you might have predicted, that information is comprised of child components: these are the <Route> components.
Just like <Switch>, <Route> is also a container component, inside which you will place the components you want to be rendered upon the activation of that particular Route. Additionally, you will need to include a path prop in the opening tag for each <Route>. The path prop will instruct the browser on what URL extension will be added to the domain name when that particular route is activated.
You can now fully build your Route Matching in the <App/> component, like so:
import React from "react"
import { Switch, Route } from "react-router-dom"
import Header from "./Header.js"
import Home from "./Home.js"
import About from "./About.js"
import ContactInfo from "./ContactInfo.js"
import ContactForm from "./ContactForm.js"
import Footer from "./Footer.js"
export default function App() {
return (
<div>
<Header />
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/contact/form">
<ContactForm />
</Route>
<Route path="/contact">
<ContactInfo />
</Route>
<Route path="/">
<Home />
</Route>
<Switch>
<Footer />
</div>
)
}
Make sure to place the components with the least specific pathways last, so that the browser can properly select which pathway you're actually trying to reach. For example, <Home/> is listed last because the pathway of "/" happens to be the starting character to each route path. So if you're routing to <Home/>, the <Switch> recognizes that there is nothing else after the "/", it skips over every other <Route> component until the one that only has "/", which will then render <Home/>. This same logic is why the route with <ContactForm/> (a component you want to be interpreted as a sub-branch of "/contact") is listed BEFORE the route with <ContactInfo/>.
NOTE: If you'd prefer to order things differently, perhaps for readability's sake, you can pass the exact prop to the particular <Route> component. This instructs the app to look for the route with that exact pathway, no matter where in the <Switch> it is placed.
Okay... You are almost there. You just need one more tool to complete the React Routing puzzle.
Route Changers (aka Navigation)
Now that you have set up your route pathways via <Switch> and <Route>, you can now place your Route Changers. These components show up in the form of <Link>, <NavLink>, or <Redirect>. All of these components have the power to change currently rendered components, based on the routes you've created in the <Switch> component.
Route Changers can be placed anywhere in the app, and they all require a to prop, which needs to have a corresponding value that matches the path given to the route you're trying to switch to. If this is done successfully, the route will change and the desired components will render on the page.
<Link> is the route changer with the broadest functionality. It simply creates an <a> element on the page that has an href attribute equal to the value of the to prop. This tag changes the route to the one with that matching path. You could create <Link> components for all our routes like this:
import { Link } from "react-router-dom"
export default LinkExamples() {
return (
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact Information</Link>
<Link to="/contact/form">Contact Form</Link>
</div>
)
}
...Pretty straightforward!
On the other hand, <NavLink> is a route changer with a more specific purpose. As the name implies, this component is meant to be included in a navigation bar. In addition to changing the current route the same way <Link> does, it also has the ability to change its appearance based on its status of being the currently active route. That's why this component needs both the props to and activeClassName. When the corresponding route is active, the <NavLink> will adopt the class name equal to the value of that activeClassName prop. It is best practice to just nest these components in a navigation bar component, perhaps called <NavBar>. This is what that component might look like:
import { NavLink } from "react-router-dom"
export default NavBar() {
return (
<nav>
<NavLink to="/">Home</Link>
<NavLink to="/about">About</Link>
<NavLink to="/contact">Contact Information</Link>
<NavLink to="/contact/form">Contact Form</Link>
</nav>
)
}
<Redirect> is the last route changer, designed to force navigation based on certain client conditions, such as whether the user is logged in and should be able to access only certain paths. I will not demonstrate this one here - perhaps another time!
Lastly, links can be used to render a route dynamically, using an id prop and fetching a specific data object based on that, to be used in the rendering of this route. The id is formatted into the <Link> like so:
<Link to={`/contacts/${id}`}>Contact Information</Link>
In Summary...
React Routing is an efficient way to create a dynamic web app for your users. If you haven't started using this powerful tool, I highly recommend it. I hope this article has helped React Router seem more straightforward.
Top comments (0)