In this guide, we'll take a look at how to create routes in a React application, programmatically navigate between routes, as well as send and retrieve data between them, using React Router. React Router is used for Client-Side Routing of resources. In this guide, we've taken a quick look at how you can programmatically navigate an application using React Router as well as how to transfer states between routes when you do. React is a massively popular library for front-end development used to create highly responsive user interfaces, and naturally, it has its own Router, which performs Client-Side Routing - the react-router-dom.
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
Let's start out by creating a simple React application via the command line:
$ npx create - react - app router - sample
Once created, let's move into the project's directory, and start the application:
$ cd router - sample $ npm start
The react-router-dom
package makes it simple to create new routes. To begin, you wrap the entire application with the <BrowserRouter>
tag. We do this to gain access to the browser's history
object. Then you define your router links, as well as the components that will be used for each route.
To demonstrate this, let's create a new file called About.js
in the /src
folder:
const About = () => {
return (
<div>
<h1>About page here!</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit, modi!
</p>
</div>
);
};
export default About;
Now, let's update the src/index.js
page and import About
from the file we've just created. Within the <BrowserRouter>
tag, we'll define our routes and components associated with them:
import { render } from "react-dom";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./App";
import About from "./About";
render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="about" element={<About />} />
</Routes>
</BrowserRouter>,
document.getElementById("root")
);
Everything should stay synced up now, and you also have access to a way of setting the history object programmatically and not via a component/container. For context, I had this problem because I occasionally use Redux-Saga to programmatically change the history object (say when a user successfully authenticates). In V4, for navigating programatically you need to access the history object, which is available through React context, as long as you have a <BrowserRouter> provider component as the top most parent in your application. The library exposes through context the router object, that itself contains history as a property. The history interface offers several navigation methods, such as push, replace and goBack, among others. You can check the whole list of properties and methods here.
There are 3 ways to render something with a Route
, by using either component
, render
or children
props, but don't use more than one in the same Route
. The choice depends on the use case, but basically the first two options will only render your component if the path
matches the url location, whereas with children
the component will be rendered whether the path matches the location or not (useful for adjusting the UI based on URL matching).
If you want to customise your component rendering output, you need to wrap your component in a function and use the render
option, in order to pass to your component any other props you desire, apart from match
, location
and history
. An example to illustrate:
import { BrowserRouter as Router } from 'react-router-dom'
const ButtonToNavigate = ({ title, history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
{title}
</button>
);
const SomeComponent = () => (
<Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)
const App = () => (
<Router>
<SomeComponent /> // Notice how in v4 we can have any other component interleaved
<AnotherComponent />
</Router>
);
This higher order component will inject the same props as Route
. However, it carries along the limitation that you can have only 1 HoC per file.
import { withRouter } from 'react-router-dom'
const ButtonToNavigate = ({ history }) => (
<button
type="button"
onClick={() => history.push('/my-new-location')}
>
Navigate
</button>
);
ButtonToNavigate.propTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired,
}),
};
export default withRouter(ButtonToNavigate);
<Redirect to="/your-new-location" push />
There are three different ways to achieve programmatic routing/navigation within components. The withRouter() higher-order function will inject the history object as a prop of the component. This object provides push() and replace() methods to avoid the usage of context. Using the withRouter() higher-order function: The <Route> component passes the same props as withRouter(), so you will be able to access the history methods through the history prop.
import { withRouter } from 'react-router-dom'; // this also works with 'react-router-native'
const Button = withRouter(({ history }) => ( <button type="button" onClick={() => { history.push('/new-location'); }} > {'Click Me!'} </button>));
import { Route } from 'react-router-dom';
const Button = () => ( <Route render={({ history }) => ( <button type="button" onClick={() => { history.push('/new-location'); }} > {'Click Me!'} </button> )} />);
const Button = (props, context) => ( <button type="button" onClick={() => { context.history.push('/new-location'); }} > {'Click Me!'} </button>);
Button.contextTypes = { history: React.PropTypes.shape({ push: React.PropTypes.func.isRequired, }),};
Inside our Hello component, we’ll import the useNavigate hook from React Router and call it at the top of the functional component. This post will answer questions like “How can I navigate on a click event in React?” or “What do I use to navigate to another URL inside a React component?”. React Router provides the <NavLink> element for us to declaratively navigate around our applications, it renders an <a href=""> for us ... Let’s get React Router setup, I’m importing components Hello and Goodbye to demonstrate how to handle navigating with hooks.
import * as React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Hello from './Hello';
import Goodbye from './Goodbye';
const App = () => (
<Router>
<Routes>
<Route exact path="/" element={<Hello />} />
<Route path="/goodbye" element={<Goodbye />} />
</Routes>
</Router>
);
export default App;
import * as React from 'react';
import { useNavigate } from 'react-router-dom';
const Hello = () => {
const navigate = useNavigate();
const handleClick = () => navigate('/goodbye');
return (
<button type="button" onClick={handleClick}>
Goodbye
</button>
);
};
export default Hello;
const GoBack = () => {
const navigate = useNavigate();
const handleClick = () => navigate(-1);
return (
<button type="button" onClick={handleClick}>
Go Back ⏪
</button>
);
};
declare function useNavigate(): NavigateFunction;
interface NavigateFunction {
(
to: To,
options ? : {
replace ? : boolean;
state ? : any;
relative ? : RelativeRoutingType;
}
): void;
(delta: number): void;
}
import React from 'react';
import { useHistory } from 'react-router-dom';
const Hello = () => {
const history = useHistory();
const handleClick = () => history.push('/goodbye');
return (
<button type="button" onClick={handleClick}>
Goodbye
</button>
);
};
export default Hello;
The Programmatic navigation in the React Router is the redirected result when the action or click of the button is performed. This is a quick process that mainly assures you of saving your time without any hassle. You can easily make quick signup or login action. There is a wide range of approaches for navigating the React Router in the programmatic aspects. React is mainly enabled with the three core concepts, such the: The main focus of the above article is to share the better way to Navigate Using React Router. React has a declarative approach to building better UIs along Redirect, which is the most recommended approach. These are suitable for navigation even when links are not used.
The action could not be triggered by simply clicking on the link. They are a suitable option for using the Link component across all the scenarios. React-router I use the Link element so that they can easily create links.
These can be natively handled with the advanced react-router, and they are called programmatic navigation. It is also internally called as this.context.transitionTo(…). When you are looking to make the navigation or adding the link from the button, then you have plenty of options. These have an extensive dropdown selection.
import { useNavigate } from 'react-router-dom';
const handleClick = (event) => {
}
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
}
return (
<a href="/" onClick={handleClick}>
Click me
</a>
);
}
These are suitable options for navigating with React Router v4+. It is enabled with <Redirect /> component. The process is mainly recommended for helping the user to navigate through routes easily.
Below are the example codes for using the Redirect component:
import React, { useState } from 'react';
import { Redirect } from 'react-router-dom';
import { userLogin } from './userAction';
import Form from './Form';
const Login = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const handleLogin = async (userDetail) => {
const success = await userLogin(userDetail);
if(success) setIsLoggedIn(true);
}
if (isLoggedIn) {
return <Redirect to='/profile' />
}
return (
<>
<h1>Login</h1>
<Form onSubmit={handleLogin} />
</>
)
}
export default Login;
Routers especially offer the history object, and they are mainly accessible, bypassing the thing on the route. It is one of the best options for manually controlling the browser’s history. The main reason is that the React Router changes with the current URL.
So the object’s history would provide better control on the individual piece of applications. Creating a simple React application using the command line is pretty convenient. Upon undergoing the process, it helps save time for the results.
$ npx create - react - app router - sample
Installing React Router:
Installing a React package with npm is a suitable option for running the simple process
npm i react - router - dom
The react-router-dom package provides better aspects for creating new routes. Accessing the react js development services gives you a better option for consulting the professional team.
When your application is added using the <BrowserRouter> tag, then you can easily gain access to the history object. It is easier to define router links along with other components for the route. Creating the new file mainly enabled with About.js also starts with /src folder
const About = () => {
return (
<div>
<h1>About page here!</h1>
<p>
Welcome! To Bosc Tech Labs
</p>
</div>
);
};
export default About;
To answer your question, you should try the React Router v5.1.0 with hooks. An update for a new useHistory hook has been introduced in the React Router >5.1.0 if what you are using is React>16.8.0 along with the components that are functional, then please use the given lines of code:- Code: import React from 'react'; import './App.css'; import NavBar from ...READ MORE Another method used is to use the composition and render a <Route> as the <Route> component is not only for the purpose of simply matching locations. You can also render a route without a path and it will always match the current location. The <Route> component passes the same props as withRouter, so you will be able to access the history methods through the history prop using the following code:-
import { useHistory } from "react-router-dom";
function HomeButton() {
const history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() = > { history.push('/new-location') }}
>
Click Me!
</button>
) } />
)
Finally, using the context* model as the React’s Context API is more stable as compared to v16 as displayed below:-
const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.push === history.push
context.history.push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
})
}
The useNavigate hook returns a function that lets you navigate programmatically, for example in an effect: It's usually better to use redirect in loaders and actions than this hook ComponentsAwait 🆕Form 🆕Link Link (RN) NavLink Navigate Outlet Route Routes ScrollRestoration 🆕 UtilitiescreateRoutesFromChildren createRoutesFromElements createSearchParams defer 🆕generatePath isRouteErrorResponse 🆕Location matchPath matchRoutes renderMatches resolvePath
import {
useNavigate
} from "react-router-dom";
function useLogoutTimer() {
const userIsInactive = useFakeInactiveUser();
const navigate = useNavigate();
useEffect(() => {
if (userIsInactive) {
fake.logout();
navigate("/session-timed-out");
}
}, [userIsInactive]);
}
declare function useNavigate(): NavigateFunction;
interface NavigateFunction {
(
to: To,
options ? : {
replace ? : boolean;
state ? : any;
relative ? : RelativeRoutingType;
}
): void;
(delta: number): void;
}