Routing
Overview
- Similar in function to a server-side router in an MVC framework- Associates a route (url) with a particular controller action
 
- React Router switches between (page/container) components when a route changes
- Back button is broken by default when page/container components change- the browser's history is not updated with a new url when page/container components change
- React Router programmatically adds entries to the browser's history
- enables the back button to work in React applications
 
There are two versions:
- BrowserRouter (react-router-dom) for web applications.
- NativeRouter (react-router-native) for use with React Native.
Installation
- Install the package npm install react-router-dom@6
- Add the script tag - index.html...<script src="/node_modules/react/umd/react.development.js"></script><script src="/node_modules/react-dom/umd/react-dom.development.js"></script>+ <script src="/node_modules/history/umd/history.development.js"></script>+ <script src="/node_modules/react-router/umd/react-router.development.js"></script>+ <script src="/node_modules/react-router-dom/umd/react-router-dom.development.js"></script><script src="/node_modules/@babel/standalone/babel.min.js"></script><script src="/node_modules/axios/dist/axios.min.js"></script><script type="text/babel" src="/main.js"></script>- ! Be sure that the - main.jsscript tag's src attribute starts with a- /or the router will not work properly when you refresh the page.
- Log the - RouterRouterDOMto verify it is installed properly- main.jsconsole.log(window.ReactRouterDOM);
- In the console you should see: {BrowserRouter: ƒ, HashRouter: ƒ, Link: ƒ, …}
Basics
- Add these styles /* styles.css */.container {border: 1px solid #ddd;margin: 30px;padding: 30px;}nav ul {list-style: none;}nav ul li {display: inline;}nav ul li:after {content: " | ";}nav ul li:last-child:after {content: "";}
- Try this code const {BrowserRouter: Router,Route,Routes,Link,NavLink,Navigate,useParams,useLocation,useNavigation,} = window.ReactRouterDOM;function Home() {return <h2>Home</h2>;}function About() {return <h2>About</h2>;}function Contact() {return <h2>Contact</h2>;}function App() {return (<Router><div><nav><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li><li><Link to="/contact">Contact</Link></li></ul></nav><div className="container"><Routes><Route path="/" element={<Home />} /><Route path="about" element={<About />} /><Route path="contact" element={<Contact />} /></Routes></div></div></Router>);}ReactDOM.createRoot(document.getElementById('root')).render(<App />);
- Change the Link tags to NavLink tags <nav><ul><li><NavLink to="/">Home</NavLink></li><li><NavLink to="/about">About</NavLink></li><li><NavLink to="/contact">Contact</NavLink></li></ul></nav>
- Add the following style - styles.css... .active {background-color: #bee5eb;padding: 10px;}
- Refresh the browser and see the navigation items are highlighted. 
Not Found (404)
- Be sure you are running a development web server like serve with the - -sflag.- package.json"scripts": {"start": "serve -s",...},...
- Change the URL to - http://localhost:5000/noroute
- The navigation renders but the page is blank. Ideally, we would like to show a - NotFoundcomponent when this happens.
3) Create a NotFound component
- Add a route for it with no path <Routes><Route path="/" element={<Home />} /><Route path="about" element={<About />} /><Route path="contact" element={<Contact />} />+ <Route path="*" element={<NotFound />} /></Routes>
- Navigate to the home route and then the contact route and notice the - NotFoundcomponent shows when visiting every route
- Navigate to the various routes again and notice that only when you manually go to a route that doesn't exist like: - /noroutethe- NotFoundcomponent renders.
URL Parameters
This example builds on the code from the previous demonstrations in this section.
- Create a - Moviemodel class.- Add it just before the App component
 class Movie {constructor(id, name, description, type) {this.id = id;this.name = name;this.description = description;this.type = type;}}
- Create an array of mock movies const movies = [new Movie(1," Titanic","A seventeen-year-old aristocrat falls in love with a kind but poor artist aboard the luxurious, ill-fated R.M.S. Titanic.","Drama"),new Movie(2," E.T. the Extra-Terrestrial","A troubled child summons the courage to help a friendly alien escape Earth and return to his home world.","Fantasy"),new Movie(3,"The Wizard of Oz",// tslint:disable-next-line:max-line-length"Dorothy Gale is swept away from a farm in Kansas to a magical land of Oz in a tornado and embarks on a quest with her new friends to see the Wizard who can help her return home in Kansas and help her friends as well.","Fantasy"),new Movie(4,"Star Wars: Episode IV - A New Hope ",// tslint:disable-next-line:max-line-length"Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a Wookiee and two droids to save the galaxy from the Empire/`s world-destroying battle-station while also attempting to rescue Princess Leia from the evil Darth Vader.","Action"),];
- Create a - Moviescomponent to list moviesfunction MovieList({ movies }) {return (<div><h2>Movies</h2><ul>{movies.map((movie) => (<li key={movie.id}><Link to={`./${movie.id}`}>{movie.name}</Link></li>))}</ul></div>);}
- Add a Route to go to the - Moviescomponent- Notice how we pass props to a the - Moviescomponent which is rendered by the React Router<Routes><Route path="/" element={<Home />} /><Route path="about" element={<About />} /><Route path="contact" element={<Contact />} />+ <Route path="movies" element={<MovieList movies={movies} />} /><Route path="movies/:id" element={<MovieDetail />} /><Route path="*" element={<NotFound />} /></Routes>
- Add a NavLink to navigate to the - Moviescomponent.<nav><ul><li><NavLink to="/">Home</NavLink></li><li><NavLink to="/about">About</NavLink></li><li><NavLink to="/contact">Contact</NavLink></li>+ <li>+ <NavLink to="/movies">Movies</NavLink>+ </li></ul></nav>
- Create a - MovieDetailcomponent to show the detail about a particular movie.function MovieDetail() {let { id } = useParams();id = Number(id);const movie = movies.find((movie) => movie.id === id);return (<div><h3>{movie.name}</h3><p>{movie.description}</p></div>);}
- Add a Route to go to the - MovieDetailcomponent....<Routes><Route path="/" element={<Home />} /><Route path="about" element={<About />} /><Route path="contact" element={<Contact />} /><Route path="movies" element={<MovieList movies={movies} />} />+ <Route path="movies/:id" element={<MovieDetail />} /><Route path="*" element={<NotFound />} /></Routes>
- Test the application and verify you can now click on a movie in the list and the movie detail route and component loads. Verify the browser's back button still works to return to the list after visiting the detail component. 
Nesting
- Edit the - MovieListcomponent to nest the- MovieDetailcomponent route inside itself.function MovieList({ movies }) {return (<div><h2>Movies</h2><ul>{movies.map((movie) => (<li key={movie.id}><Link to={`./${movie.id}`}>{movie.name}</Link></li>))}</ul>+ <div style={{ marginLeft: "40px" }}>+ <Routes>+ <Route path=":id" element={<MovieDetail />} />+ </Routes>+ </div></div>);}
- Remove the - MovieDetailroute from the- Appcomponent. Add an astericks (*) after the- moviesroute so it can find the nested routes....<Routes><Route path="/" element={<Home />} /><Route path="about" element={<About />} /><Route path="contact" element={<Contact />} />+ <Route path="movies/*" element={<MovieList movies={movies} />} />- <Route path="movies/:id" element={<MovieDetail />} /><Route path="*" element={<NotFound />} /></Routes>
- Refresh the browser and notice that the movie detail now shows below the movie list after clicking a movie link.