Redirect on button click in React - reactjs

Can anyone please tell me how redirect works in react?
I'm from Angular background and trying to learn React.
I have a small application, where I want to redirect the user to profile component on click of a button.
This is a very basic requirement but there's no proper documentation available (or I'm not able to find one).
Any help will be appreciated.
Here's my code:
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
<BrowserRouter>
<Switch>
<Route path="/" exact render={props => <Index {...props} />} />
<Route path="/login-page" exact render={props => <Login {...props} />} />
<Route path="/profile-page" exact render={props => <Profile {...props} />} />
<Route path="/dashboard" exact render={props => <Dashboard {...props} />} />
<Redirect to="/" />
</Switch>
</BrowserRouter>,
<Button color='primary' onClick={e => this.viewProfile()}>View Profile</Button>
viewProfile = function () {
console.log("clicked");
}

Use the Link component from react-router-dom:
<Link to="/profile">View profile</Link>
Check out the docs as well, they provide a lot of examples

You can call up the useHistory() hook to navigate.
import { useHistory } from "react-router-dom";
const yourComponent = () => {
const history = useHistory();
viewProfile = function() {
history.push("/new-url");
};
return (
<Button color="primary" onClick={viewProfile}>
View Profile
</Button>
);
};
If you are using a class component you can wrap it withRouter() to gain access to the same history object.
import React from "react";
import { withRouter } from "react-router";
class YourComponent extends React.Component {
viewProfile = function() {
const { history } = this.props;
history.push("/new-url");
};
render() {
return (
<Button color="primary" onClick={this.viewProfile}>
View Profile
</Button>
);
}
}
export default withRouter(YourComponent);

React Router comes with a Link component that can be used for this. Just import it, set the destination in the to prop, and wrap your Button with it:
import { Link } from "react-router-dom";
<Link to='/profile-page'>
<Button color='primary' onClick={e => this.viewProfile()}>View Profile</Button>
</Link>
viewProfile = function () {
console.log("clicked");
}
Have a look at the React Router docs, they've got a lot of useful info!

Adding this solved my problem.
import { Redirect } from 'react-router'
state = {
redirect: false
}
const { redirect } = this.state;
if (redirect) {
return <Redirect to='/profile-page'/>;
}
viewProfile = function () {
console.log("clicked");
this.setState({ redirect: true })
}
thanks #tarzen chugh, #Good Samaritan for you response

Nomenclature is important when you are first learning a new framework :)
Strictly speaking a redirect will
Rendering a <Redirect> will navigate to a new location. The new location will override the current location in the history stack
What you want is navigating to the profile page. There are two ways you can achieve this
Through JSX Link.
Programmatically with the history object.

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
class Test extends Component{
constructor(props){
super(props);
this.state ={}
}
viewProfile = () => {
const {history} = this.props;
history.push('profile-page');
}
}
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
class Test extends Component{
constructor(props){
super(props);
this.state ={}
}
viewProfile = () => {
const {history} = this.props;
history.push('profile-page');
}
render(){
return(
<Button
color='primary'
onClick={() => this.viewProfile()}>
View Profile
/>
);
}
}
export default withRouter(Test);

Here you can use withRouter HOC to do redirects.
import { withRouter } from "react-router";
class Component extends React.Component {
viewProfile = function () {
console.log("clicked");
this.props.history.push('/main');
}
render(){
return (
<Button color='primary' onClick={e => this.viewProfile()}>View Profile</Button>
)
}
}
export default withRouter(Component);
Ref: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md

Do like this :-
<Button color='primary' onClick={() => this.viewProfile()}>View Profile</Button>
viewProfile= () => {
return (
<Redirect
to={{
pathname: "/profile-page",
}}
/>
);
};

Related

Link & useHistory.push from 'react-router-dom' changes URL but Not reloading page

I would like to have a button to redirect to homepage on 404 and errorBoundary pages.
I am getting history object and url changes on button click.
However, it does not reload homepage.
Link & useHistory works perfectly on other pages except these two !
tried Router & BrowserRouter both from 'react-router-dom', but none of them worked.
Any advice ? Thank you !!
versions
react 17.0.2
react-dom 17.0.2
react-router-dom 5.2.0
routes.js
import React, { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
const routes = () => (
<Router history={history}>
<ErrorBoundary>
<Suspense fallback={<Loading />}>
<App />
<Switch>
<Route path="/login" component={Login} />
<Route exact path={['/', '/reserves']} component={ReservesMain} />
<PrivateRoute path="/reserve/:id" component={ReserveMain} />
<PrivateRoute path="/managers" component={ManagersMain} />
<PrivateRoute path="/manager/:id" component={ManagerMain} />
<Route component={NotFound} />
</Switch>
</Suspense>
</ErrorBoundary>
</Router>
);
notFound.js
import { useHistory, Link } from 'react-router-dom';
import Button from '../components/shared/button';
...
export default function NotFound() {
const history = useHistory();
const onRedirect = () => history.push('/');
return (
<div>
<h1>404. Not Found. </h1>
<p>Oops! Something's missing...</p>
<p>The page does not exist or is unavailable.</p>
<Link to={'/'}>redirect button</Link>
<Button name="Go Home" onClick={onRedirect} />
</div>
);
}
errorBoundary.js
import React from 'react';
import { connect } from 'react-redux';
import { useHistory } from 'react-router-dom';
import Button from '../components/shared/button';
const BadRequest = ({ status }) => [
<h1 key="be-1">
{status ? <span>{status}.</span> : null} This page isn't working.
</h1>,
<h2 key="be-2">Your client has issued a malformed or illegal request.</h2>,
<h2 key="be-3">If the problem continues, contact the engineer department.</h2>,
];
const SystemError = ({ status }) => [
<h1 key="se-1">
{status ? <span>{status}.</span> : null} Something went wrong.
</h1>,
<h2 key="se-2">Oops! We're experiencing an internal Server Error.</h2>,
<h2 key="se-3">Please try again later.</h2>,
];
export const ErrorComponents = ({ status }) => {
const history = useHistory();
const onRedirect = () => history.push('/');
return (
<>
<div style={rootStyle}>
<div style={innerStyles}>
{status === 400 ? <BadRequest status={status} /> : <SystemError status={status} />}
<Button name="Go Home" onClick={onRedirect} />
</div>
</>
);
};
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: null };
}
static getDerivedStateFromError(error) {
return { error };
}
componentDidCatch(error, info) {
if (process.env.NODE_ENV === 'development') {
console.log(`error : ${error.name}, message: ${error.message || 'null'}`);
console.log(`info : ${JSON.stringify(info)}`);
}
}
render() {
if (this.state.error) {
return <ErrorComponents status={this.props.asyncApi.status} />;
}
return this.props.children;
}
}
const mapStateToProps = (state) => ({
asyncApi: state.asyncApi,
});
export default connect(mapStateToProps, null)(ErrorBoundary);

React-HashRouter: Redirect displays blank page

Apologies if it sounds stupid question. I'm trying to redirect user to the content pages of the app when they are signed in. My current implementation correctly changes the URL in the address bar but doesn't render a component and shows a blank page. Is there something i'm missing in here. Could you please suggest what am i'm missing ?
I tried googling it but couldn't make it work. Here are some of the links i tried.
1- https://tylermcginnis.com/react-router-programmatically-navigate/
2- https://learnwithparam.com/blog/redirect-route-in-react-router/
3- Programmatically navigate using react router
Login Component
class Login extends React.Component {
handleSubmit(e) {
e.preventDefault();
var value = true;
localStorage.setItem('userLoggedIn', JSON.stringify(value));
this.setState({
toUsers: true
})
//this.props.history.push('/users')
}
render() {
if (this.state.toUsers === true) {
return <Redirect to="/users" />
}
return (
<div className="Login">
<form onSubmit={this.handleSubmit}>
Email
<input
type="text"
value={this.state.email}
onChange={this.handleEmailChange}
/>
Password
<input
type="text"
value={this.state.password}
onChange={this.handlePasswordChange}
/>
<button>
Login
</button>
</form>
</div>
);
}
}
export default Login;
App component:
import React, { Component } from 'react';
import { BrowserRouter, HashRouter, Switch, Route } from 'react-router-dom';
import Navigation from './common/Navigation';
import Users from './users/Users.jsx';
import Roles from './roles/Roles.jsx';
import ProtectedRoute from './authentication/ProtectedRoute.jsx';
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return <Navigation>
<Switch>
<Route exact path="/users" component={Users} />
<Route exact path="/roles" component={Roles} />
<Route render={() => <div>Not Found</div>} />
</Switch>
</Navigation>
}
}
Component which decides if login page should be displayed or the content pages of the application
export default class AppAuthenticated extends React.Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
toUsers: false,
isUserLoggedIn: false
};
}
componentDidMount() {
const isUserLoggedIn = JSON.parse(localStorage.getItem('userLoggedIn'));
this.setState({
isUserLoggedIn: isUserLoggedIn
});
}
render() {
return (
<>
{this.state.isUserLoggedIn ? (
<App />
) : (
<Login />
)}
</>
);
}
}
Main App Component which renders the app
import React from 'react'
import ReactDOM from "react-dom";
import App from './pages/App'
import { BrowserRouter, HashRouter, Switch, Route } from 'react-router-dom';
import PropTypes from "prop-types";
import { withRouter } from "react-router";
import Login from './pages/authentication/Login.jsx';
import AppAuthenticated from './pages/authentication/AppAuthenticated.jsx';
ReactDOM.render(
<HashRouter>
<AppAuthenticated />
</HashRouter>,
document.getElementById("root")
);
Expected Behavior: When user is signed in successfully, they should be redirected to the "App" component where I've defined all the routes that logged in user can access
In your app.js, pass a prop to your login component that can change the container state to render your content pages.
setLoggedIn = ()=>{
this.setState({isUserLoggedIn: true});
}
render() {
return (
<>
{this.state.isUserLoggedIn ? (
<App />
) : (
<Login loginSuccess={this.setLoggedIn} />
)}
</>
);
}
Then in your Login Component...
handleSubmit(e) {
e.preventDefault();
var value = true;
localStorage.setItem('userLoggedIn', JSON.stringify(value));
this.setState({
toUsers: true
})
this.props.loginSuccess();
//this.props.history.push('/users')
}
setLoggedIn = ()=>{
this.setState({isUserLoggedIn: true});
}
render() {
return (
<>
{this.state.isUserLoggedIn ? (
<App />
) : (
<Login loginSuccess={this.setLoggedIn} />
)}
</>
);
}
this is missing in your passing props #maddy

React-Router-Dom Link not working in a nested component. Update url parameters, but component doesn't load on click. Works if I refresh after click

I have a NavBar that's on multiple pages that allows me to search for an user. After the searching, clicking on it should re-direct me to the user page via Link from react-router-dom. The problem is this only works on the main page, and doesn't work when clicking from an user's page.
I've tried adding WithRouter to all my related components (containers, parents, and the children). Also tried fiddling with the Route pathing / exact pathing syntax to no avail.
*Removed components imports and non-relavant code for clarity.
/app.jsx
import React from 'react';
import { Provider } from 'react-redux';
import {
Route,
Redirect,
Switch,
Link,
HashRouter,
withRouter,
} from 'react-router-dom';
import { AuthRoute, ProtectedRoute } from '../utils/route_utils';
const App = () => (
<div className="main">
<HashRouter>
<Switch>
<AuthRoute exact path="/" component={LoginContainer} />
<AuthRoute exact path="/signup" component={SignupContainer} />
<ProtectedRoute exact path="/feed" component={FeedContainer} />
<ProtectedRoute exact path="/users/:userId" component={GreetingContainer} />
<ProtectedRoute exact path="/posts/:postId" component={PostShowContainer} />
<ProtectedRoute exact path="/upload" component={Upload} />
<ProtectedRoute exact path="/accounts/edit" component={AccountsEditContainer} />
<Route component={Errors} />
</Switch>
</HashRouter>
</div>
);
export default withRouter(App);
/greeting_container.jsx
import React from 'react';
import { withRouter } from 'react-router-dom';
const mapStateToProps = (state, ownProps) => {
...
};
const mapDispatchtoProps = (dispatch) => ({
....
});
export default withRouter(connect(mapStateToProps, mapDispatchtoProps)(Greeting));
/greeting.jsx
import React from 'react';
import { Link } from 'react-router-dom';
import NavBarContainer from '../nav_bar/nav_bar_container';
class Greeting extends React.Component {
constructor(props) {
super(props);
this.renderPosts = this.renderPosts.bind(this);
}
render() {
if (!this.props.user) return null;
const profileUser = parseInt(this.props.match.params.userId)
const user = this.props.user
return (
<div className="user-page-container">
<Modal currentUser={user} />
<NavBarContainer />
</div>
}
export default Greeting;
/nav_bar_container.jsx
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import NavBar from './nav_bar';
const mapStateToProps = (state) => {
....
};
const mapDispatchToProps = (dispatch) => ({
...
});
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(NavBar));
/nav_bar.jsx
import React from 'react';
import { Link, withRouter } from 'react-router-dom';
import NavBarSearch from './nav_bar_search';
const NavBar = (props) => {
return (
<div>
< NavBarSearch
fetchSearchedUsers={props.fetchSearchedUsers}
searchResults={props.searchResults}
/>
</div>
);
};
export default withRouter(NavBar);
/nav_bar_search.jsx
import React from 'react';
import NavBarSearchResults from './nav_bar_search_results';
import { withRouter } from 'react-router-dom';
class NavBarSearch extends React.Component {
constructor(props) {
super(props);
this.state = {
searchInput: ''
}
this.generateSearch = this.generateSearch.bind(this)
}
render() {
return (
<div >
<input className="search-bar-test" onChange={this.generateSearch} type="text" placeholder='Search' />
{this.state.searchInput ? <NavBarSearchResults
searchResults={this.props.searchResults}
handleClick={this.handleClick}
// key={this.props.searchResults.id}
/> : null
}
</div>
)
}
}
export default withRouter(NavBarSearch);
/nav_bar_search_results.jsx
import React from 'react';
import { withRouter, Link } from 'react-router-dom';
const NavBarSearchResults = function({ searchResults, handleClick }) {
let results = searchResults ? Object.entries(searchResults).map((result) =>
<Link className="search-links" to={`/users/${result[0]}`} onClick={e => handleClick} key={result[0]}>
<div className="search-results-item">
<img className="search-results-image" src={result[1].photoUrl} />
{result[1].username}
</div>
</Link>
) : null
return (
<div className="search-results-container">
{results}
</div>
);
}
export default withRouter(NavBarSearchResults);
Once again, it is the Link in the Nav_Bar_Search_Results.jsx file that is not working. This file is nested several levels deep starting from the Greeting.jsx file. The string interpolation I'm doing is the user_id number. Please recall that the url parameters updates and the page works if I CLICK and REFRESH page, but not on first click alone.
The correct user page should render as specified by the url parameters

React-Router v4. How to append a parameter to URL? TypeError: history.push is not a function

I'm using i18-next library to switch languages in my app. So it's done without reloading a page. The language switch is done via:
render() {
const toggle = lng => i18n.changeLanguage(lng);
return (
<a href="javascript:void(0)" onClick={()=>{ toggle();}}></a>
)
I'd make such functionality: once the language is switched add to a URL a language param. So once change is occured it should looks like: www.website.com/xx
I've read mostly all topics regarding Rect-Router v4 and history but all suggestions didn't work in my project. Some of them are related to obsolete functionality. I've also tried few example with withRouter, but nothing worked...
How it could be achieved in my case?
index.js:
import { Router, Route, Switch } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
const customHistory = createBrowserHistory();
...
return (
<I18nextProvider i18n={i18n}>
<div>
<Router history={customHistory}>
<Switch>
<Route exact path="/:lng?" component={Page} />
<Route path={`/:lng?/someURL`} component={Page}/>
...
<Route component={NoMatch} />
</Switch>
</Router>
<ModalContainer />
</div>
</I18nextProvider>
)
navigation component:
handleClick() {
**append URL with lang param**
console.log(history);
-> history: History { length: 1, scrollRestoration: "auto", state: null }
history.push('/redirected');
-> TypeError: history.push is not a function
}
render() {
const toggle = lng => i18n.changeLanguage(lng);
return (
<a href="javascript:void(0)" onClick={()=>{ toggle(this.props.event); this.handleClick(); }}></a>
)
Should it be done with function as handleClick() or this event should be global? The languages are switched from several components.
React-Router V4.2.0
Your navigation component needs to use a Link or NavLink component from react-router. There is no need for you manually access the router from context.
import {NavLink} from 'react-router-dom';
class NavComponent extends React.Component {
render() {
const { i18n } = this.props;
const toggle = lng => i18n.changeLanguage(lng);
if (this.props.event) {
return (
<li><NavLink className={(this.props.spanClassName)} onClick={()=> toggle(this.props.event)} to={this.props.event}/></li>
);
}
else
return null;
}
};
well, I came to this solution. Maybe it will be helpful for some people.
If there are more better ways to achieve it, please post your answer.
But one problem left. Once I'm in www.website.com/xx/someURL and press language switch the xx part of the URL should be swapped with new param but someURL should remain. Anybody knows how to make it?
index.js:
import { Router, Route, Switch } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
const customHistory = createBrowserHistory();
render() {
return (
<I18nextProvider i18n={i18n}>
<div>
<Router history={customHistory}>
<Switch>
<Route exact path="/:lng?" component={Page} />
<Route path={`/:lng?/someURL`} component={Page}/>
<Route component={NoMatch} />
</Switch>
</Router>
<ModalContainer />
</div>
</I18nextProvider>
)
}
nav component:
import PropTypes from "prop-types";
class NavLink extends React.Component {
static contextTypes = {
router: PropTypes.object
}
constructor(props, context) {
super(props, context);
}
handleClick(path) {
this.context.router.history.push(path);
}
render() {
const { i18n } = this.props;
const toggle = lng => i18n.changeLanguage(lng);
if (this.props.event) {
return (
<li><a href="javascript:void(0)" onClick={()=>{ toggle(this.props.event); this.handleClick(this.props.event); }}><span className={(this.props.spanClassName)}></span></a></li>
)
}
}
};

React Router Pass Param to Component

const rootEl = document.getElementById('root');
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route exact path="/">
<MasterPage />
</Route>
<Route exact path="/details/:id" >
<DetailsPage />
</Route>
</Switch>
</BrowserRouter>,
rootEl
);
I am trying access the id in the DetailsPage component but it is not being accessible. I tried
<DetailsPage foo={this.props}/>
to pass parameters to the DetailsPage, but in vain.
export default class DetailsPage extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="page">
<Header />
<div id="mainContentContainer" >
</div>
</div>
);
}
}
So any idea how to pass the ID on to the DetailsPage ?
I used this to access the ID in my component:
<Route path="/details/:id" component={DetailsPage}/>
And in the detail component:
export default class DetailsPage extends Component {
render() {
return(
<div>
<h2>{this.props.match.params.id}</h2>
</div>
)
}
}
This will render any ID inside an h2, hope that helps someone.
If you want to pass props to a component inside a route, the simplest way is by utilizing the render, like this:
<Route exact path="/details/:id" render={(props) => <DetailsPage globalStore={globalStore} {...props} /> } />
You can access the props inside the DetailPage using:
this.props.match
this.props.globalStore
The {...props} is needed to pass the original Route's props, otherwise you will only get this.props.globalStore inside the DetailPage.
Since react-router v5.1 with hooks:
import { useParams } from 'react-router';
export default function DetailsPage() {
const { id } = useParams();
}
See https://reacttraining.com/blog/react-router-v5-1/
Use render method:
<Route exact path="/details/:id" render={(props) => (
<DetailsPage id={props.match.params.id}/>
)} />
And you should be able to access the id using:
this.props.id
Inside the DetailsPage component
In addition to Alexander Lunas answer ...
If you want to add more than one argument just use:
<Route path="/details/:id/:title" component={DetailsPage}/>
export default class DetailsPage extends Component {
render() {
return(
<div>
<h2>{this.props.match.params.id}</h2>
<h3>{this.props.match.params.title}</h3>
</div>
)
}
}
Use the component:
<Route exact path="/details/:id" component={DetailsPage} />
And you should be able to access the id using:
this.props.match.params.id
Inside the DetailsPage component
This is for react-router-dom v6 (I highly suggest using functional components for this)
It's somewhat painful for react-router-dom to keep changing syntax and rules. But here goes nothing.
You can use both useParams and useSelector to solve this
import { useParams } from 'react-router';
import { useSelector } from 'react-redux';
const Component = () => {
const { id } = useParams(); //returns the :id
const page = useSelector((state) => state.something[id]); //returns state of the page
return <div>Page Detail</div>;
}
export default Component;
BUT, the problem persist when you also have an action creator and you want to pass it as a props in connect function
export const connect(mapStateToProps, mapDispatchToProps)(Component)
since we are using useParams, it won't be passed to mapStateToProps that we created
const mapStateToProps = (state, ownProps) => {
console.log(ownProps) //wont recognize :id
//hence
return {
someReducers: state.someReducers[id] //would return an error: 'id' is not defined
};
};
on the other hand, you can't entirely ignore the connect function since you need mapDispatchToProps to work with your component.
The workaround to this is to create a Higher Order Component withRouter function yourself. This was a deprecated react-router-dom helper.
//make this
import { useParams, useLocation, useNavigate } from 'react-router';
import { connect } from 'react-redux';
import { yourActionCreator } from '../actionCreator';
const withRouter = (Child) => {
return (props) => {
const location = useLocation();
const navigation = useNavigate();
const params = useParams();
return (
<Child
{...props}
params={params}
navigate={navigate}
location={location}
/>
);
};
};
const Component = () => {
// your component...
return <div> Page Detail </div>
};
export mapStateToProps = (state, ownProps) => {
console.log(ownProps) // would contain the :id params
return {
//something
}
};
const mapDispatchToProps = {
yourActionCreator
}
export withRouter(connect(mapStateToProps, mapDispatchToProps)(Component));
Here's typescript version. works on "react-router-dom": "^4.3.1"
export const AppRouter: React.StatelessComponent = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path="/problem/:problemId" render={props => <ProblemPage {...props.match.params} />} />
<Route path="/" exact component={App} />
</Switch>
</BrowserRouter>
);
};
and component
export class ProblemPage extends React.Component<ProblemRouteTokens> {
public render(): JSX.Element {
return <div>{this.props.problemId}</div>;
}
}
where ProblemRouteTokens
export interface ProblemRouteTokens {
problemId: string; }
Another solution is to use a state and lifecycle hooks in the routed component and a search statement in the to property of the <Link /> component. The search parameters can later be accessed via new URLSearchParams();
<Link
key={id}
to={{
pathname: this.props.match.url + '/' + foo,
search: '?foo=' + foo
}} />
<Route path="/details/:foo" component={DetailsPage}/>
export default class DetailsPage extends Component {
state = {
foo: ''
}
componentDidMount () {
this.parseQueryParams();
}
componentDidUpdate() {
this.parseQueryParams();
}
parseQueryParams () {
const query = new URLSearchParams(this.props.location.search);
for (let param of query.entries()) {
if (this.state.foo!== param[1]) {
this.setState({foo: param[1]});
}
}
}
render() {
return(
<div>
<h2>{this.state.foo}</h2>
</div>
)
}
}
FOR version 6 ( 2022 )
Note: using useParams you can easily get your params in your component.
look at the example below
import React from "react";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import Home from "./compo/home";
import About from "./compo/about";
import Login from "./compo/login";
import "./styles.css";
const App = () => {
return (
<Router>
<div className="container">
<Link to="/home">Home</Link>
<Link to="/about">About</Link>
<Link to="/login">Login</Link>
</div>
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/login" element={<Login />} />
<Route path="/login/:name" element={<Login />} />
</Routes>
</Router>
);
};
export default App;
Login Component
import { useParams } from "react-router-dom";
const Login = () => {
let { name } = useParams();
return <h1>i am {name ? <b>{name}</b> : "login"}</h1>;
};
export default Login;
if you are using class component, you are most likely to use GSerjo suggestion. Pass in the params via <Route> props to your target component:
exact path="/problem/:problemId" render={props => <ProblemPage {...props.match.params} />}
In the latest version of (react-router-dom#6.3.0), you can do it like this:
<Route path="path" element={<YourComponent type="simple" />} />
Here, type is the input passed to YourComponent
I was working on react-router-dom version 6.3.0 and above solution didn't resolve my problem. Then I use something like this and it worked:
<Route exact path='/payment-status/:userId/:orderId' element={<PaymentStatus/>}/>
And on PaymentStatus.js page I did like this:
import { useParams } from 'react-router-dom'
export const PaymentStatus = () => {
let {userId, orderId}=useParams()
return (
<div>
<h2>order ID : {orderId}</h2>
<h2>user ID : {userId}</h2>
</div>
)
}
It worked for me. I hope it may help someone. Thanks!
try this.
<Route exact path="/details/:id" render={(props)=>{return(
<DetailsPage id={props.match.params.id}/>)
}} />
In details page try this...
this.props.id
Simple example with Class, HoC and Router v5
package.json
"react-router-dom": "5.3.1",
"react-router": "5.3.1",
"#types/react-router-dom": "5.3.3",
// YourComponent.tsx
import React from 'react';
import { RouteComponentProps, withRouter } from 'react-router';
export interface PathParams {
id: string;
}
export interface Props extends RouteComponentProps<PathParams> {}
export interface State {}
class YourComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {};
console.log(props.match.params) // { id: 1 }
// TypeScript completions
console.log(props.match.params.id) // 1
}
render() {
return <></>;
}
}
export default withRouter(YourComponent);
// App.tsx
import './App.css';
import React from 'react';
import { Route, Switch, Router } from 'react-router-dom';
import YourComponent from './YourComponent';
function App(): JSX.Element {
return (
<Router>
<Switch>
<Route
path="/details/:id"
component={() => <YourComponent />}
/>
</Switch>
</Router>
);
}
export default App;

Resources