Changing the URL in react-router v4 without using Redirect or Link [duplicate]
I'm using react-router v4 and material-ui in my React app. I was wondering how to change the URL once there is a click on a GridTile
within GridList.
My initial idea was to use a handler for onTouchTap
. However, the only way I can see to redirect is by using the components Redirect
or Link
. How could I change the URL without rendering those two components?
I've tried this.context.router.push('/foo')
but it doesn't seem to work.
Solution 1:
Try this,
this.props.router.push('/foo')
warning works for versions prior to v4
and
this.props.history.push('/foo')
for v4 and above
Solution 2:
I'm using this to redirect with React Router v4:
this.props.history.push('/foo');
Solution 3:
React Router v4
There's a couple of things that I needed to get this working smoothly.
The doc page on auth workflow has quite a lot of what is required.
However I had three issues
- Where does the
props.history
come from? - How do I pass it through to my component which isn't directly inside the
Route
component - What if I want other
props
?
I ended up using:
- option 2 from an answer on 'Programmatically navigate using react router' - i.e. to use
<Route render>
which gets youprops.history
which can then be passed down to the children. - Use the
render={routeProps => <MyComponent {...props} {routeProps} />}
to combine otherprops
from this answer on 'react-router - pass props to handler component'
N.B. With the render
method you have to pass through the props from the Route
component explicitly. You also want to use render
and not component
for performance reasons (component
forces a reload every time).
const App = (props) => (
<Route
path="/home"
render={routeProps => <MyComponent {...props} {...routeProps}>}
/>
)
const MyComponent = (props) => (
/**
* @link https://reacttraining.com/react-router/web/example/auth-workflow
* N.B. I use `props.history` instead of `history`
*/
<button onClick={() => {
fakeAuth.signout(() => props.history.push('/foo'))
}}>Sign out</button>
)
One of the confusing things I found is that in quite a few of the React Router v4 docs they use MyComponent = ({ match })
i.e. Object destructuring, which meant initially I didn't realise that Route
passes down three props, match
, location
and history
I think some of the other answers here are assuming that everything is done via JavaScript classes.
Here's an example, plus if you don't need to pass any props
through you can just use component
class App extends React.Component {
render () {
<Route
path="/home"
component={MyComponent}
/>
}
}
class MyComponent extends React.Component {
render () {
/**
* @link https://reacttraining.com/react-router/web/example/auth-workflow
* N.B. I use `props.history` instead of `history`
*/
<button onClick={() => {
this.fakeAuth.signout(() => this.props.history.push('/foo'))
}}>Sign out</button>
}
}
Solution 4:
This is how I did a similar thing. I have tiles that are thumbnails to YouTube videos. When I click the tile, it redirects me to a 'player' page that uses the 'video_id' to render the correct video to the page.
<GridTile
key={video_id}
title={video_title}
containerElement={<Link to={`/player/${video_id}`}/>}
>
ETA: Sorry, just noticed that you didn't want to use the LINK or REDIRECT components for some reason. Maybe my answer will still help in some way. ; )