Redirection in a React App with Class Components
Handling redirection in a React app is very common in web applications. A link can navigate to another page of your site. A button can trigger some logic that leads to a redirection. With single page applications, this is handled differently as opposed to a server side rendered application. In this post, we'll be using the package react-router-dom v5 to handle navigation between different pages.
Using the Redirect Component in a React App
React-router-dom includes a redirect component that you can use to navigate to another page. This method uses the component state to tell when to navigate. It might be more useful to use this method if we want to pass in more props for the redirection.
import React, { Component } from "react";import { Redirect } from "react-router-dom";class MyComponent extends Component {constructor(props) {super(props);this.state = { shouldRedirect: false };}handleClick = () => {this.setState({ shouldRedirect: true });};render() {const { shouldRedirect } = this.state;if (shouldRedirect) {return <Redirect to="/another-page" />;}return <button onClick={this.handleClick}>Redirect to new page</button>;}}export default MyComponent;
In the above scenario, it's not ideal to be redirecting using this method. The Link component would easily suffice. Using the redirect component method is useful when you have complex logic for redirection. For instance: wanting to perform a redirection when an API request is successful. This examples uses axios, but you could also use the fetch method.
import axios from "axios";import React, { Component } from "react";import { Redirect } from "react-router-dom";class MyComponent extends Component {constructor(props) {super(props);this.state = { shouldRedirect: false, message: "" };}handleChange = (event) => {this.setState({ [event.target.name]: event.target.value });};handleSubmit = async () => {try {const { data } = await axios.get("https://YOUR_ENDPOINT");if (data) {this.setState({ shouldRedirect: true });}} catch (error) {console.error(error);}};render() {const { shouldRedirect, message } = this.state;if (shouldRedirect) {return <Redirect to="/another-page" />;}return (<form onSubmit={this.handleSubmit} noValidate><input value={message} onChange={this.handleChange} /><button>Submit</button></form>);}}
Using withRouter and the History Prop
This method uses the history prop from the withRouter higher order component. We don't need to maintain another piece of state to handle the redirection. This is useful if we just need to redirect to a new page without any specific props needing to be passed down.
import axios from "axios";import React, { Component } from "react";import { withRouter } from "react-router-dom";class MyComponent extends Component {constructor(props) {super(props);this.state = { message: "" };}handleChange = (event) => {this.setState({ [event.target.name]: event.target.value });};handleSubmit = async () => {const { history } = this.props;try {const { data } = await axios.get("https://YOUR_ENDPOINT");if (data) {history.push("/another-page");}} catch (error) {console.error(error);}};render() {const { message } = this.state;return (<form onSubmit={this.handleSubmit} noValidate><input value={message} onChange={this.handleChange} /><button type="submit">Submit</button></form>);}}export default withRouter(MyComponent);
Conclusion
These are two methods for handling redirection in a React app with class components using the react-router-dom v5 package. The first method using the redirect component offers more flexibility. You will be able to pass in extra props down through the redirection. The second method using the history prop does not have much flexibility, but not having to maintain an extra piece of state can be a cleaner solution.