May 20, 2021
React-Router-Dom Official Documentation
SPA (Single Page Application) literally means an application consisting of a single page. Traditional web pages fetch new HTML from the server and re-render the entire page whenever a user navigates to a different page. This method becomes inefficient with the increasing amount of information available on the web. Hence, modern web applications delegate the responsibility of rendering views to the user’s browser using libraries like React. The initial application is loaded and executed in the browser, and JavaScript updates only the necessary parts when user interactions occur. If new data is needed, only specific data is fetched from the server through APIs.
Today’s web pages have many pages and diverse screens due to the vast amount of information they provide. Therefore, even in SPAs, routing to different pages is essential. React itself does not include this functionality, so we use the react-router-dom
library to implement it.
The basic form (low-level interface) of all Router components, and in actual app, one of the 5 Router components is used mostly.
<BrowserRouter>
<HashRouter>
<MemoryRouter>
<NativeRouter>
<StaticRouter>
Among them, <BrowserRouter>
and <HashRouter>
are mainly used.
You need to wrap the highest-level component with Router in order to switch between pages.
One of the
<Router/>
types that uses HTML5’s history API to update UI.
Since <HashRouter>
uses URL hashes, it is suitable for static pages.
Since dynamic pages are usually created with requests and responses, <BrowserRouter>
is commonly used.
The Link component navigates to a different address when clicked.
export default function App() {
return (
<>
<div>header</div>
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/1?name=kim">Users</Link>
</li>
</ul>
</nav>
</div>
</Router>
</>
)
}
In HTML, <a> also navigates to a different address. However, in React, <a> is not used because it triggers page reloading. Instead, <Link> only changes the browser’s address (URL).
<Link>
simply changes the URL, while <Route>
renders the component corresponding to that URL.
App.js
import React from 'react'
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
import User from './components/User'
export default function App() {
return (
<>
<div>header</div>
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/1">Users</Link>
</li>
</ul>
</nav>
<Switch>
<Route path="/about" component={About} />
<Route path="/:id" component={User} />
<Route path="/" component={Home} />
</Switch>
</div>
</Router>
</>
)
}
About.js
import React, { useEffect } from 'react'
function About(props) {
useEffect(() => console.log(props), [])
return <div>About...</div>
}
export default About
The component rendered by Route receives props.
Props Output👇
The Route props include the following three objects:
match contains information on how <Route path>
matched with the URL.
The match object has properties like:
directory/:id
in the URL<Route>
history object holds the stack of URLs navigated so far, allowing manipulation like arbitrary path changes or going back.
length : Total length of history stack
action : Recent action performed (PUSH, REPLACE or POP)
location : Recent path information
push(path, [state]) : Pushes a new path to history stack for navigation
replace(path, [state]) : Replaces recent path in history stack for navigation
go(n) : Moves history stack pointer to nth position
goBack() : Moves back to previous page
goForward() : Moves forward to next page
block(prompt) : Controls PUSH/POP actions in history stack
location object contains current page’s information.
<Link to='/1?name=kim'>users</Link>
pathname: Current page’s path
search: Current URL’s query string
hash: Current page’s hash
App.js
import React from "react";
import { BrowserRouter
as Router, Switch, Route, Link } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import User from "./components/User";
export default function App() {
return (
<>
<Router>
.
.
.
{/* <Switch>*/}
<Route path="/about" component={About} />
<Route path="/users" component={User} />
<Route path="/" component={Home} />
{/*</Switch>*/}
</div>
</Router>
</>
);
}
What will happen if you remove the switch statement? Although “User” is clicked, both “User” and “Home” are rendered.
import React from "react";
import { BrowserRouter
as Router, Switch, Route, Link } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import User from "./components/User";
export default function App() {
return (
<>
<Router>
.
.
.
<Switch>
<Route path="/about" component={About} />
<Route path="/users" component={User} />
<Route path="/" component={Home} />
</Switch>
</div>
</Router>
</>
);
}
The switch statement checks the path and renders the first match. Therefore, /user matches <Route path="/users" component={User} />
and ignores <Route path="/" component={Home} />
.
To access location
, match
, and history
objects used in unrendered components by <Route component={component name}>
, withRouter must be used.
import React from 'react'
import { withRouter } from 'react-router-dom'
function Side({ history }) {
const clickHandler = () => {
history.push('/')
}
return <button onClick={clickHandler}>Go Home!</button>
}
export default withRouter(Side)
Although Side component is not rendered by Route, withRouter is used to enable page navigation using history object.