React – Routing Parameters, Redirects, & Handling Page Refresh

Table of Contents
Overview
This post will show examples of setting up routes and passing parameters. Also how to redirect to another route from both a class and function component. In addition to the routing and redirect, there are a couple of strategies for deploying the react application to a server while maintain the ability to refresh the page without getting a 404 error.
Prerequisites
Make sure you have the following library installed. The examples below were written with React Router Dom version 5.2.0.
npm install react-router-dom@5.2.0
Application Router Component
App Router Component
In the file labeled AppRouter.js under “./components/“. This is the router component in app.js. With a layout (app bar and side menu drawer) routes are passed to the content area of the layout to make it responsive.
Also use the exact key word for routes like the root path
<Route exact path="/" component={HomeComp} />
import React from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import HomeComp from './../components/Home';
import FunctionComp from './../components/FunctionComponent';
import ClassComp from './../components/ClassComponent';
export default function AppRouter(props) {
return (
<div>
<Switch>
<Route exact path="/" component={ListComp} />
<Route path="/class/:id" component={ClassComp} />
<Route path="/product/:id" component={FunctionComp} />
</Switch>
</div>
);
}
App.js
Example below uses router component labeled AppRouter from above inside a <Router> tag. To enable the use for browser Forward and Back buttons to work import createBorwserHistory from “history“;
Code for “./app.js“
import React from 'react';
import AppRouter from './components/AppRouter';
import { BrowserRouter as Router} from 'react-router-dom';
import { createBrowserHistory } from "history";
// Enable Browser History for Back and Forward Button
export const appHistory = createBrowserHistory();
function App() {
return (
<div>
<Router history={appHistory}>
<AppRouter />
</Router>
</div>
);
}
export default App;
Passing Parameters
In order to send the parameter simply add a colon before the parameter name.
Example :id
export default function AppRouter(props) {
return (
<div>
<Switch>
<Route exact path="/" component={ListComp} />
<Route path="/class/:id" component={ClassComp} />
<Route path="/product/:id" component={FunctionComp} />
</Switch>
</div>
);
}
The parameter is prefixed with a colon. Example below is a parameter labeled :eventId
path="/class/:eventId"
Function Component – useParams() Hook
You can get the parameters with the useParams() hook. Also added the Link from react-router-dom to go back to the home page.
Example:
import React from 'react'
import { useParams } from "react-router-dom";
import { Link } from 'react-router-dom';
export default function Product(props) {
let { id } = useParams();
return (
<div>
<Link to="/"> <- Back</Link>
<br/><br/>
Product {id}
</div>
)
}
Class Component – props
For class components you cannot use the useParams() hook. To get the URL parameter, use the property this.props.match.params.Id.
Example:
import React from 'react'
class ClassComp extends React.Component {
constructor(props) {
super(props);
}
render() {
const id = this.props.match.params.id;
return (
<React.Fragment>
Class {id}
</React.Fragment>
)
}
}
export default ClassComp;
There are a lot of variations to this. This is a simple example to pass and receive a URL parameter with the router.
If you just look at the raw data from the URL param in this.props, this is what you will see.
The eventId is under eventId -> match. – > params -> eventId.

Navigation
Navigation with react-router-dom is accomplished with Link. Link Provides declarative, accessible navigation around your application
Navigate With <Link/>
import { Link } from 'react-router-dom';
...
<Link to={`/product/2`}>Home</Link>
Navigate by Button (Material UI)
import Button from '@material-ui/core/Button';
import { Link } from 'react-router-dom';
...
<button type="button" component={Link} to={`/product/2`}>Open</button>
Navigate by Menu Item (Material UI)
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import { Link } from 'react-router-dom';
export default function NavMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}>
<MenuItem onClick={handleClose} component={Link} to="/home">Home</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
)
}
Redirects
In order to navigate to a new location from a component there are a couple of different ways to accomplish this. This depends on the component type. To read more about the React Router Redirects click here or try the examples below for Class and Function Components.
Class Component
Import Redirect from react-router-dom.
import { Redirect } from 'react-router-dom';
Using the JSX tag Redirect under the render() event by changing the state of a boolean variable. In this example redirect is the name of the variable initially set to false.
constructor(props) {
this.state = { redirect: false }
// ...
hideAlert = (event) => {
this.setState({showAlert: false, redirect: true});
}
// ...
render() {
if (this.state.redirect) {
return <Redirect to='/landing'/>;
}
Function Component
Import useHistory from from react-router-dom.
import { useHistory } from 'react-router-dom';
Then in your function push() the new route.
let history = useHistory();
onConfirmAlert = event => {
history.push('/landing');
}
Handling Refresh on the Server
After deploying the building files, there are a couple of ways to mitigate a page refresh error.
LINUX
Update the .htaccess files with the following.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
To force a redirect to HTTPS add the following in addition to the above.
# Redirect to HTTPS
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://csjobsearch.com/$1 [R,L]
Windows IIS
If your React app is in a subfolder with the API at the root you can use the API’s web.config and add a custom error for 404.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Static Files" stopProcessing="true">
<match url="([\S]+[.](html|htm|svg|js|css|png|gif|jpg|jpeg))" />
<action type="Rewrite" url="/{R:1}"/>
</rule>
<rule name="React Router" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
If the React Application is at the root then open the IIS Errors

Update the custom 404 page to redirect to the root and then handle the refresh.

You must be logged in to post a comment.