score:283
React Router v6 - React 17+ (updated 01/14/2022)
import React, {useCallback} from 'react';
import {useNavigate} from 'react-router-dom';
export default function StackOverflowExample() {
const navigate = useNavigate();
const handleOnClick = useCallback(() => navigate('/sample', {replace: true}), [navigate]);
return (
<button type="button" onClick={handleOnClick}>
Go home
</button>
);
}
Note: For this answer, the one major change between v6 and v5 is useNavigate
is now the preferred React hook. useHistory
is deprecated and not recommended.
React Router v5 - React 16.8+ with Hooks
If you're leveraging React Hooks, you can take advantage of the useHistory
API that comes from React Router v5.
import React, {useCallback} from 'react';
import {useHistory} from 'react-router-dom';
export default function StackOverflowExample() {
const history = useHistory();
const handleOnClick = useCallback(() => history.push('/sample'), [history]);
return (
<button type="button" onClick={handleOnClick}>
Go home
</button>
);
}
Another way to write the click handler if you don't want to use useCallback
const handleOnClick = () => history.push('/sample');
React Router v4 - Redirect Component
The v4 recommended way is to allow your render method to catch a redirect. Use state or props to determine if the redirect component needs to be shown (which then trigger's a redirect).
import { Redirect } from 'react-router';
// ... your class implementation
handleOnClick = () => {
// some action...
// then redirect
this.setState({redirect: true});
}
render() {
if (this.state.redirect) {
return <Redirect push to="/sample" />;
}
return <button onClick={this.handleOnClick} type="button">Button</button>;
}
Reference: https://reacttraining.com/react-router/web/api/Redirect
React Router v4 - Reference Router Context
You can also take advantage of Router
's context that's exposed to the React component.
static contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
push: PropTypes.func.isRequired,
replace: PropTypes.func.isRequired
}).isRequired,
staticContext: PropTypes.object
}).isRequired
};
handleOnClick = () => {
this.context.router.push('/sample');
}
This is how <Redirect />
works under the hood.
React Router v4 - Externally Mutate History Object
If you still need to do something similar to v2's implementation, you can create a copy of BrowserRouter
then expose the history
as an exportable constant. Below is a basic example but you can compose it to inject it with customizable props if needed. There are noted caveats with lifecycles, but it should always rerender the Router, just like in v2. This can be useful for redirects after an API request from an action function.
// browser router file...
import createHistory from 'history/createBrowserHistory';
import { Router } from 'react-router';
export const history = createHistory();
export default class BrowserRouter extends Component {
render() {
return <Router history={history} children={this.props.children} />
}
}
// your main file...
import BrowserRouter from './relative/path/to/BrowserRouter';
import { render } from 'react-dom';
render(
<BrowserRouter>
<App/>
</BrowserRouter>
);
// some file... where you don't have React instance references
import { history } from './relative/path/to/BrowserRouter';
history.push('/sample');
Latest BrowserRouter
to extend: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js
React Router v2
Push a new state to the browserHistory
instance:
import {browserHistory} from 'react-router';
// ...
browserHistory.push('/sample');
Reference: https://github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md
score:-1
again this is JS :) this still works ....
var linkToClick = document.getElementById('something');
linkToClick.click();
<Link id="something" to={/somewhaere}> the link </Link>
score:0
If you'd like to extend
the Link
component to utilise some of the logic in it's onClick()
handler, here's how:
import React from 'react';
import { Link } from "react-router-dom";
// Extend react-router-dom Link to include a function for validation.
class LinkExtra extends Link {
render() {
const linkMarkup = super.render();
const { validation, ...rest} = linkMarkup.props; // Filter out props for <a>.
const onclick = event => {
if (!this.props.validation || this.props.validation()) {
this.handleClick(event);
} else {
event.preventDefault();
console.log("Failed validation");
}
}
return(
<a {...rest} onClick={onclick} />
)
}
}
export default LinkExtra;
Usage
<LinkExtra to="/mypage" validation={() => false}>Next</LinkExtra>
score:2
Ok, I think I was able to find a proper solution for that.
Now, instead of sending <Link/>
as prop to Document, I send <NextLink/>
which is a custom wrapper for the react-router Link. By doing that, I'm able to have the right arrow as part of the Link structure while still avoiding to have routing code inside Document object.
The updated code looks like follows:
//in NextLink.js
var React = require('react');
var Right = require('./Right');
var NextLink = React.createClass({
propTypes: {
link: React.PropTypes.node.isRequired
},
contextTypes: {
transitionTo: React.PropTypes.func.isRequired
},
_onClickRight: function() {
this.context.transitionTo(this.props.link.props.to);
},
render: function() {
return (
<div>
{this.props.link}
<Right onClick={this._onClickRight} />
</div>
);
}
});
module.exports = NextLink;
...
//in MasterPage.js
var sampleLink = <Link to="/sample">Go To Sample</Link>
var nextLink = <NextLink link={sampleLink} />
<Document next={nextLink} />
//in Document.js
...
var Document = React.createClass({
render: function() {
return (
...
<div>{this.props.next}</div>
...
);
}
});
...
P.S: If you are using the latest version of react-router you may need to use this.context.router.transitionTo
instead of this.context.transitionTo
. This code will work fine for react-router version 0.12.X.
score:2
React Router 4
You can easily invoke the push method via context in v4:
this.context.router.push(this.props.exitPath);
where context is:
static contextTypes = {
router: React.PropTypes.object,
};
score:2
Answers here are outdated.
React Router 6
useHistory
is deprecated v6 uses the useNavigate
hook instead.
import { useNavigate } from 'react-router-dom'
const navigate = useNavigate()
navigate(`/somewhere`, { replace: true })
score:8
or you can even try executing onClick this (more violent solution):
window.location.assign("/sample");
score:25
In the version 5.x, you can use useHistory
hook of react-router-dom
:
// Sample extracted from https://reacttraining.com/react-router/core/api/Hooks/usehistory
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>
);
}
score:95
React Router 4 includes a withRouter HOC that gives you access to the history
object via this.props
:
import React, {Component} from 'react'
import {withRouter} from 'react-router-dom'
class Foo extends Component {
constructor(props) {
super(props)
this.goHome = this.goHome.bind(this)
}
goHome() {
this.props.history.push('/')
}
render() {
<div className="foo">
<button onClick={this.goHome} />
</div>
}
}
export default withRouter(Foo)
Source: stackoverflow.com
Related Query
- How to pass params into link using React router v6?
- In react router v4 how does one link to a fragment identifier?
- How to link to nested routes in React Router
- How to add dynamic code inside of a React Router Link component
- I can not get the state from react router Link component using useLocation. So how can I pass it?
- React router dom - Link. How can I put an ID into the path of Link
- How to make react router Link load page like anchor tag?
- How to delay the redirect of a React Router Link component for 1 second?
- How to pass props using react router link v6?
- How to add Link from react router dom to the submit button with the default Submit validation
- How to set active only one link with react router for multiple url state?
- How can I link an input to a react router link
- How to link to Routes inside the component rendered by another Route with React Router
- React - how to make innerHtml inside the react router link to take the width of the parent element
- How do I implement a Logout functionality from a React Router Link to imports an array?
- Can't figure out how to Link state with React Router
- How to use React Router Link on a landing page?
- How to call react router DOM link inside a function call/manually
- How to pass a prop from one component to another when using react router link
- How to link an image to a page dynamically with React Router Dom?
- How to use React Router Link component inside an Ant Design Tab component
- How to reload a page using react router Link component?
- How can I pass props from one component to another using Link and router in react
- How to set default className in react router link changed
- React router 4 - Why is my component only rendered on manually setting the url but not on clicking a Link with same url?
- How can I construct a link to a "neighbour" resource in react router v6?
- How to link to certain page upon form submission using React Router
- How to put Link from react router dom inside Material UI table
- How to pass props/params/state to a Route with Link in React Router 5.2.0?
- How do I select Link tag in React Router Dom with CSS?
More Query from same tag
- Issues with response from express file to front end (React)
- How to update state of component in componentDidUpdate() without being stuck in an infinite re render?
- React-Router/Redux browser back button functionality
- TypeError: _SchoolProduct__WEBPACK_IMPORTED_MODULE_2___default.a.map is not a function
- How to style the dropdown UI in the basic html select element in React?
- React Redux Store Updates - Changes Don't Update Component
- React conditional rendering depending on focus of input text field
- Jest tests with enzyme and connect() giving `import connectAdvanced from '../components/connectAdvanced';`
- Can't use props in child component when using Formik for building a wizard
- Compare two array's and disable element if the id's are equal
- TypeError: email.indexOf is not a function in React using react-mailchimp-subscribe
- Setting a Max Length for a Material-UI AutoComplete that uses free solo
- undefined method `map' for "1,2":String
- React .createClass() scroll to ref: scrollIntoView not a function
- Why does resource.data in Firestore rules work incorrectly?
- Module not found: Can't resolve 'react-dom/unstable-native-dependencies'
- Map of React Components not re rendering on State Change
- React, check state if key pair exists depending on parameter
- Map over children with top level React Children API
- redux-sagas generator yield failing inside callback
- I'm trying to replicate this figma design
- How do I pass an array of data to and use it in a Typescript React component?
- How can componentDidMount wait for a value from redux store before executing (without using setTimeout)?
- React Hook "useState" is called in function
- React cannot pass props to parent component
- I want to reset my form after clicking submit in reactjs. I have tried making another method. but it does not work
- How Can I Add Two Functions for "value" in TextField?
- Can't style material-ui with its own props
- How to get "real" value from input[type=number]
- RadioGroup Onchange is not firing in React