React-router: allow undefined routes to pass to server - javascript

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.

Related

Unable to redirect to reset password link without being logged

I'm new to react router and implementing a log in system, however, since i didn't build the whole app i'm not quite sure why all the Routes redirect to /#/ if the user is not logged in..
I'm using React Router and I want someone to be able to click on a link on an email that takes them to
http://localhost:3001/auth/forgot8b8dc686ee38320f7f5dd7b858e62a402cd2f0bb#/
This is how i'm referencing the link in react router
` {
path: "/forgot",
component: loadable(() => import("./layout/forgot/forgot")),
pure: false,
exact: true
},`
`<ConnectedRouter history={history}>
<IndexLayout>
<Switch>
<Route exact path='/forgot' component={Forgot} />
<Route exact path="/" render={() => <Redirect to="/foo/all" />} />
{routes.map(route => (
<Route
path={route.path}
component={route.component}
key={route.path}
exact={route.exact}
/>
))}
<Route component={NotFound404} />
</Switch>
<ToastContainer autoClose={8000} hideProgressBar={true} />
</IndexLayout>
</ConnectedRouter>`
If i'm not logged in the above just redirects me to my home page and I cannot even see that URL being called in the console, however if i am logged in, I can see that component being rendered on my dashboard (i don't want it to be rendered inside my dashboard I want it to be a page non logged in users can use to reset their password similar to my home page)
Essentially I want a route non logged in users can go to without it being inside my dashboard.
My forgot page with the field where users can input their new password is located in the .layout folder that is also the location of my IndexLayout
`import IndexLayout from "./layout";`
My dashboard is only supposed to get render if the user is logged in
`return this.props.user.authenticated && this.props.user ? (
<Dashboard children={children} user={user} />
) `
However I don't see why this would affect what i can and can't see.
I normally use standard express and pug to build my apps and i would just do a app.get('forgot:token'(req,res,next)=>{etc}) etc..
Given that your URL is http://localhost:3001/auth/forgot8b8dc686ee38320f7f5dd7b858e62a402cd2f0bb#/
The path pattern /forgot doesn't match this. Which is why you're not landing on the Forgot component.
You could change your URL structure to something like:
.../forgot/8b8dc686ee38320f7f5dd7b858e62a402cd2f0bb
Then you can retrieve the token using React Router URL Params like this:
<Route exact path='/forgot/:token' component={Forgot} />

How to route React application login page if server returns 401 error code

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 ?

Ignore react-router route

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" />

How to handle front-end and back-end paths on browser refresh

I'm using React, React-router and Play Framework to serve and render an application.
This is what my Routes.jsx looks like:
const Routes = (
<Route path="/">
<Route component={App}>
<Route path="attributes/:itemId" component={AttributesContainer}/>
<IndexRoute component={ItemsContainer}/>
</Route>
</Route>
);
export default Routes
As you can see, path /attributes/:itemId renders a component called AttributesContainer.
This path is called from ItemsContainer in this function:
_onClickAttributes(itemId) {
browserHistory.push({pathname: '/attributes/' + itemId});
}
Everything works just fine there. But if I refresh the browser while in /attributes/:itemId, back-end returns
Action Not Found
For request 'GET /attributes/5'
instead of the front end component. I understand the browser is doing a get request and that's why I get this message.
So, what's the best technique to handle this?

How to get parent parameter in nested route?

I have the following basic structure of nested routes/components for a react app:
/users -> UsersList
/users/:id -> UserLayout
/users/:id/ -> UserProfile
/users/:id/settings -> UserSettings
/users/:id/blah -> YetAnotherComponent
What I'm trying to figure out, in the context of react router v4, is how to access the :id parameter in the UserSettings component. I can access it fine in the UserLayout component, but nowhere else further downstream.
My main router definition lies in a Home component, but all the user-specific routes contain the same header information so I want all the user-specific routes to be nested. My current structure has these nested routes defined in the UserLayout component. However, no matter what I do to the layout component's route definition, I cannot get any other route than the "index" route (UserProfile) to render. When trying to access UserSettings or any other route, my top level 404 route gets hit instead.
Here's the relevant JSX (snippets of the actual components' render functions):
Home
<main>
<Switch>
<Route exact path="/login" component={Login} />
<Route exact path="/users" component={UsersList} />
<Route exact path="/users/:id" component={UserLayout} />
<Route exact path="/" component={Home} />
<Route component={NoMatch} />
</Switch>
</main>
UserLayout
<div>
<Switch>
<Route path={`${match.url}/settings`} component={UserSettings} />
<Route path="/users/:id/blah" component={YetAnotherComponent} />
</Switch>
<Route path="/users/:id" component={UserProfile} />
</div>
In the UserLayout component I've tried both path formats shown in the Switch and have tried turning on/off exact matching. The only thing I can come up with is using the Route component's render parameter to pass the id parameter, but that just seems wrong. Is that my only option?
Of course only a few minutes after I post, I figured it out. In my top-level route config, I had set the /user/:id to require an exact match. This meant that when I navigated to /user/:id/anything_else react router didn't load UserLayout at all and thus didn't get the chance to test the remainder of the routes I had configured.
So I changed this from my home component:
<Route exact path="/users/:id" component={UserLayout} />
...to this:
<Route path="/users/:id" component={UserLayout} />
... and now all is well with the world.

Categories

Resources