There's a component on '/example' route. When I navigate to that path, the component being rendered. The problem is that I need to ignore rendering component and get redirected to the external link (which happen to have the same route) - '/example'. Is there any way for me to ignore or get around react-router route?
Here's a one-liner for using React Router to redirect to an external link:
<Route path='/privacy-policy' component={() => {
window.location.href = 'https://example.com/1234';
return null;
}}/>
You can try using Redirect
<Route path="/example" render={() => {
return <Redirect to="//external.url/example" />
}} />
Or if you have a <Switch> around the routes you can shorten it:
<Redirect from="/example" to="//external.url/example" />
Related
I have a component called Posts that lists all posts in a blog. I have links around the post's usernames which link to the same (Posts) component only with a different URL containing a user id to query the posts with. The problem is that the Posts component will not re-render upon visiting this URL, although the URL in the browser changes accordingly.
Routes in App.js:
<Routes>
<Route path='/' element={<Posts/>}/>
<Route path='/user/:user_id/posts' element={<Posts/>}/>
</Routes>
Links in Posts.js
<Link to={`/user/${post.user.id}/posts`}>
{post.user.username}
</Link>
I have tried various things including trying to add a key to the component but it didn't work. I also saw a "force re-render" code snippet but it was for a previous version of React Router.
How can I force the rendering of the Posts component in React Router v6?
If Posts is rendered by a route that has changing route params
<Routes>
<Route path='/' element={<Posts/>}/>
<Route path='/user/:user_id/posts' element={<Posts/>}/>
</Routes>
then it should "listen" for changes to the route's match params.
In Posts use the useParams hook to access the user_id route match param, and use an useEffect hook with a dependency on user_id to run/rerun any logic.
import { useParams } from 'react-router-dom';
...
const { user_id } = useParams();
useEffect(() => {
if (user_id) {
// do something with user_id
}
}, [user_id]);
If Posts is a class component, then either convert it to a function component so it can use React hooks, or create a wrapper component or a new withRouter replacement to use the hook and inject params as a prop.
I'm not sure but maybe this kind of code would work I think...?
<Routes>
<Route path='/' element={props => <Posts {...props} />}/>
<Route path='/user/:user_id/posts' element={props => <Posts {...props} />}/>
</Routes>
And if it does not works,
maybe just using <a> instead of <Link> might be work.
<a href={`/user/${post.user.id}/posts`}>
{post.user.username}
</a>
I have a React application that splitted into many small components. I have five main pages that users can navigate;
I'm using nested routing as you can see below;
<Router>
<Switch>
<Route path="/login">
<PageLogin />
</Route>
<PrivateRoute path="/app">
<Router>
<Switch>
<Route path={`/app/dashboard`}/>
<Route path="/app/user">
<PageUsers ></PageUser>
</Route>
<Route path="/app/edit">
<PageEdit />
</Route>
<Route path="/app/manage">
<PageManage/>
</Route>
<Route path='/app/j3'>
<PageJ3></PageJ3>
</Route>
</Switch>
</Router>
</PrivateRoute>
</Switch>
</Router>
I have defined the /app route as a private route. I want only authenticated users to reach this pages.
I have defined private route function component as below;
const PrivateRoute = ({ children, ...rest }) => {
this.isAuthenticated = cookieCheck() ? true : false;
return (
<Route
{...rest}
render={({ location }) =>
this.isAuthenticated ? (
children
) : (
<Redirect
to={{
pathname: "/login",
state: { from: location }
}}
/>
)
}
/>
);
}
It redirects the users to login page if isAuthenticated is false.
That logic works. But I also have detail pages inside these main navigation pages. For example PageEdit has a page inside called PageEditDetail . This detail page opens when user clicks an object inside the page. It makes an api call using fetch. I'm loading the header with token that I've received on login. If the token is expired server returns 401 error and of course page doesn't show anything from user but I want the page to be redirected to login page in this case.
I've tried adding the below script to callback of the fetch method but it didn't worked;
if (fetchedRes.status === 401) {
return <Redirect to='/login' />
}
How can I redirect the React application to login page from child component according to a parameter ?
I'm migrating a react application and I'm trying to split it. Basically, I would like to redirect some client-side react routes to absolute urls (or relative, but at least go with a server roundtrip, where reverse proxying is done)
Note that
react-router 3.0.0
react-router-redux 4.0.7
The app have these urls
http://myhost/ => homepage
http://myhost/someroute1 => a first route
http://myhost/someroute2 => a second route
http://myhost/someroute3 => a third route
Everything is inside react right now.
Routing looks like this :
<Provider store={store}>
<Router history={history}>
<Route path="/" component={Root}>
<IndexRoute component={Home} />
<Route path="/someroute1" component={Route1} />
<Route path="/someroute2" component={Route2} />
<Route path="/someroute3" component={Route3} />
</Route>
</Router>
</Provider>
The goal is to redirect, say, routes "/" and "/someroute2" to static urls (server urls). As so :
http://myhost/ => http://anotherhost/
http://myhost/someroute1 => keep react routing
http://myhost/someroute2 => http://anotherhost/anotherroute5
http://myhost/someroute3 => keep react routing
The question is simple : is is possible to replace, in a clean way, a react router route with an absolute url ?
I heard about Redirect and IndexRedirect components, but I can't figure how to use it properly, and, due to a lack of react / react-router, I can't figure if there would be any dangerous side-effects (in history for example).
Use Route's render prop instead of component. That way, you can specify a function to be called instead of a component to be instantiated. In the function, perform the navigation the old-fashioned way, using window.location.href:
<Route
path="/someroute2"
render={() => {
window.location.href = "http://anotherhost/anotherroute5";
return null;
}}
/>
Partially based on #brub answer, I've found a solution using a dumb component.
import React, { Component } from 'react'
export default class MyRedirectRoute extends Component {
componentDidMount() {
window.location.href = //my url here
}
render() {
return null
}
}
That I pass like this
<Route path="/someroute3" component={MyRedirectRoute} />
Though, I'm still not aware of a few things :
Is this a recommended solution ?
Are there any history side-effect ?
Is there any better (more react-router) solution than window.location.href ? I tried this.context.history without any success...
I'm waiting for feedback / better solution before accepting my own answer
You probably don't need React Router for this. The creator of React Router suggests using the <a> tag.
I haven't tried it but syntactically you could do it like this:
<Route
path="/someroute2"
render={() => <Redirect to="http://anotherhost/anotherroute5" />}
/>
fI currently have the following routes defined in my application:
/
/selectSteps
/steps
/steps/alpha
/steps/beta
/steps/charlie
Which could also be visualised like this:
- (home)
- selectSteps
- steps
- alpha
- beta
- charlie
My root component looks like this:
<Route path="/" exact component={Home} />
<Route path="/select-steps" render={() => <StepSelectorContainer />} />
<Route path="/steps" component={StepsContainer} />
My Steps component does this:
steps.map(step => (
<Route
path={fullPathForStep(step.uid)}
key={shortid.generate()}
render={() => <StepContainer step={step} />}
/>
This all works nicely, but I don't want steps to exist as route in its own right. Only its child routes should be visitable. So I'm looking to lose the /steps route to leave my routes as:
/
/selectSteps
/steps/alpha
/steps/beta
/steps/charlie
How should I configure my routes for this? Ideally, hitting /steps would redirect to the first child route.
Actually, it's pretty straightforward...
Use Redirect component to... well, redirect.
<Redirect from="/steps" exact to="/steps/whatever" />
exact prop guarantees you won't be redirected from sub-route.
Edit: after all, Redirect does support exact (or strict) props. No need to wrap in Route. Answer updated to reflect that.
Pedr,
I think that this will solve your problem.
<Route path="/" exact component={Home} />
<Route path="/select-steps" render={() => <StepSelectorContainer />} />
<Route path="/steps" component={StepsComponent} />
And then in your StepsComponent render method, you can do this.
<Switch>
{steps.map(step => (
<Route
path={fullPathForStep(step.uid)}
key={shortid.generate()}
render={() => <StepContainer step={step} />}
/>}
<Redirect from="/steps" exact to="/steps/alpha" />
</Switch>
What this will do is render your steps component because it the route begins with /steps. After that is rendered, then it will render one of the nested routes based off the url. If the url is just "/steps", then it will redirect to the initial route listed here, in this case "/steps/alpa" by rendering the redirect. The Switch will make it so that it only renders one of the routes.
Credit to Andreyco for the redirect code.
I hope this helps.
My stack: Django app with React/react-router/flux frontend.
I'm managing some static pages (plus 404 page, etc) server-side, and want to configure my router to pass any undefined routes through to the server.
Here's how things are set up now:
let routes = (
<Route name="app" path="/" handler={ App }>
<Route name="register" handler={ Register }/>
<Route name="login" handler={ Login }/>
<Route name="refer" handler={ Refer }/>
<Route name="help" handler= { Help }/>
<Route name="list-property" handler= { ListProperty }/>
<DefaultRoute handler={ Home }/>
</Route>
);
router = Router.create({ routes, location });
router.run((Handler, state) => {
React.render(<Handler {...state} />, rootEl);
});
mysite.com/register will get routed through the react router to my Register page component, but I want mysite.com/thanks to hit my server (so django can manage the route). Right now I get a blank page.
I'm perusing the documentation here but can't find what I need: http://rackt.github.io/react-router/#NotFoundRoute
Maybe I'm overlooking something... thanks!
If you want certain paths to hit the server redirect to those paths using a standard anchor redirect or similar rather than use the Router.Link to navigate.