A primary ingredient in any traditional or single-page app is routing. Routing is the ability to navigate from one page to another. In a typical single-page app, you can use React Router to do the routing for you. But as the app grows and the global state gets complicated, you may need to use a state management library like Redux.
The app may also be running on a different path (https://example.com/app) and not on the root domain, adding additional complexity. In this guide, you will learn how to set up a base URL in React Router and how to combine Redux seamlessly.
This section covers how to add a base URL in a simple React app using React Router.
The first step is to install the react-router-dom
dependency in your app.
1npm i react-router-dom
Next, add the page components as routes in the app.
1const HomePage = () => {
2 return (
3 <div>
4 <h2>Home</h2>
5 </div>
6 );
7};
8
9const ContactPage = () => {
10 return (
11 <div>
12 <h2>Contact</h2>
13 </div>
14 );
15};
16
17const ProfilePage = () => {
18 return (
19 <div>
20 <h2>Profile</h2>
21 </div>
22 );
23};
Pass the above page components as children to the Route
component and wrap with the Switch
component from react-router-dom
.
1import { Route, Switch } from "react-router-dom";
2// ...
3
4const Main = () => {
5 return (
6 <div className="app">
7 <Navbar />
8 <div className="content">
9 <Switch>
10 <Route exact path="/">
11 <HomePage />
12 </Route>
13 <Route path="/contact">
14 <ContactPage />
15 </Route>
16 <Route path="/profile">
17 <ProfilePage />
18 </Route>
19 </Switch>
20 </div>
21 </div>
22 );
23};
Import the BrowserRouter
component from react-router-dom
. The BrowserRouter
component has a basename
prop, which accepts a string as its value in case the React app is hosted from a sub-directory.
1import { BrowserRouter } from "react-router-dom";
2
3const App = () => {
4 return (
5 <BrowserRouter basename="/app">
6 <Main />
7 </BrowserRouter>
8 );
9};
Adding basename
in the BrowserRouter
component ensures that all the links in the routes are prefixed with the base URL. For example, <Link to='/contact' />
will be rendered as <a href='/app/contact'>
.
In this section, you will integrate Redux with the above React Router set up.
The connected-react-router
package is recommended by the maintainers of React Router for deeper Redux integration. To install connected-react-router
, run the following command.
1npm i connected-react-router
The history
object can be used to change the browser's history session programmatically. To create a history
object, import the createBrowserHistory
function from the history
package and create the object as shown below.
1import { createBrowserHistory } from "history";
2
3const history = createBrowserHistory();
The history
package is a dependency of react-router-dom
, so you don't have to install it again.
Next, connect the history object to the store. To do that, import the connectRouter
helper function from connected-react-router
package and provide the created history object.
1import { connectRouter } from "connected-react-router";
2import { createStore } from "redux";
3
4const reducer = (initialState, action) => {
5 // ...
6};
7
8const store = createStore(connectRouter(history)(reducer));
routerMiddleware
to ReduxrouterMiddleware
will dispatch the history actions to the Redux store. Use the applyMiddleware
helper function from redux
to include routerMiddleware
in the app.
1import { connectRouter, routerMiddleware } from "connected-react-router";
2import { createStore, applyMiddleware } from "redux";
3
4const store = createStore(
5 connectRouter(history)(reducer),
6 applyMiddleware(routerMiddleware(history))
7);
You're almost done. The last step is to use the ConnectedRouter
component and pass the history object as a prop. Make sure you wrap the ConnectedRouter
component with the Provider
component from react-redux
.
1import { ConnectedRouter } from "connected-react-router";
2import { Provider } from "react-redux";
1const App = () => {
2 return (
3 <Provider store={store}>
4 <ConnectedRouter history={history}>
5 <BrowserRouter basename="/app">
6 <Main />
7 </BrowserRouter>
8 </ConnectedRouter>
9 </Provider>
10 );
11};
Redux is a vital component of the React ecosystem, so you need to understand how to integrate React-Router and Redux and how they work together. React Router has an excellent section on deep Redux integration that you may want to read for a better understanding of how things work under the hood.