React Router v6 Navigate to absolute path from subrouter - react-router

Suppose we have this situation:
<Routes>
<Route path="/" element={<Master/>}/>
<Route path="/login" element={<Auth/>}>
<Route path="" element={<AuthInitiate/>}/>
<Route path="callback" element={<AuthCallback/>}/>
</Route>
</Routes>
Suppose we currently are in /login/callback. Inside the AuthCallback component I use:
const navigate = useNavigate()
navigate("/")
The result is that i get redirected to /login, so I understand that the "/" refers to the relative subroute we are in (that is, /login). This is super useful in a lot of situations, but here I just to redirect with respect to the absolute path, so "/" should mean exactly / and not /login.
How should I do?
Be aware I'm referring to the new React Router v6.
EDIT: I had something else redirecting the route, the code instead works exactly as expected and navigate("/") from subroute indeed navigate to root level. There are no issues with navigation from subroutes, sorry.

Even though OP's problem is already resolved, I think it may be worth leaving this answer here for future travelers:
Use a leading slash to navigate to an absolute path:
const navigate = useNavigate();
// Absolute path:
navigate('/login/auth');
// Relative paths:
navigate('login');
navigate('login/auth');
navigate('../login');
Also noteworthy: In React Router v6 trailing slashes are ignored.

Related

Extend <Route> element of react-router-dom to run custom logic on route match

I'm using react-router v6 and I want to be able to have the following snippet in my code, and have document.title to be set to the value specified in title attribute of the Route element.
<Routes>
<Route path="/groups" element={<GroupsPage />} title='Groups - Student Portal`/>
<Route path="/classes" element={<ClassesPage />} title='Classes - Student Portal`/>
</Routes>
I can't seem to find a hook that would give me a currently matched route without parsing the routes myself or storing them as a javascript object.
Question #1: is there a way to get properties of a currently matched route?
Additionally, Routes implementation of createRoutesFromChildren link is not OCP-friendly. I can't think of a way to solve this without rewriting both Routes and Route with a slight modification just to allow extra properties on a route.
Question #2: how can I add custom properties to the Route element?

React-Router v3 handling Child Routes data fetch

I am really struggling with ChildRoutes in react-router and any help direction would be much appreciated.
I want to define my routes something in this manner.
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="about" component={About}/>
<Route path="users" component={Users}>
<Route path="/user/:userId" component={User}/>
</Route>
<Route path="*" component={NoMatch}/>
</Route>
</Router>
The main problem is with Users. So when user hits /users I load all the users from API.
And when he navigates to users/1 , I would read the data from Users state by getting the userId from routeParams and the fetch details of user 1.
I want the Child Routes to work as say if someone pastes the URL /users/1 directly in the browser then the route would still load my Users component which will load all the users and the waterfall flow will continue.
Now here is my issue , the user detail is completely a new page in my app, so even though the router loads Users compoennt I want to navigate and render User component if my URL exactly matches the pattern /users/:userId. I am not sure how I can achieve this with react-router v3.0.4 . So happy path is first component Users get loaded and then when user is clicked the path changes to users/:userId and the User Component renders.
But the complicated path is when someone loads users/:userId directly in the browser the Users component should get mounted and then based on the location.path the User component should get rendered.
Again Any help with this would be much appreciated.
Thanks
Why don't you create a parent component User that loads the data on entry, then put UserProfile (or whatever this is loading) as a child component... it would look something like this:
import React, { Component } from 'react';
const mapDispatchToProps = {
getDate: someAction.getData
}
#connect(state => state, mapDispatchToProps);
export default class User extends Component {
componentWillMount() { ...loadData }
render() { return {...this.props.children} }
}
Then in your routes
<Route path="users" component={Users}>
<Route path="user" component={User}>
<Route path="/:id" component={UserProfile} />
</Route>
</Route>
I could have gone in more detail here, but I think I explain the general concept. Let me know how it goes!
Using this method you can guarantee data is loaded every time.

url refresh nor working as expected with create-react-app and react-router-redux on DEV

I'm trying to implement minimal routing in my create-react-app using react-router-redux . Documentation indicates that, if not using create-react-app, one needs to configure Webpack in order for the url refresh to work as expected (a setting related to 'history fall back'), but if using create-react-app this should automatically work. However, in my development environment, url refresh is not working as expected. Details: if the second route's url is current in the browser when I do a page refresh, then the second route is re-loaded, while I would have expected the main route (with path "/") would load instead. My index.js includes the following:
render(
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Route exact path="/" component={MyHomeComponent} />
<Route exact path="/roster" component={Roster} />
</div>
</ConnectedRouter>
</Provider>,
document.getElementById('root')
)
Could this be a documentation bug, or am I forgetting something in my code? Suggestions are very much appreciated.
A refresh should maintain the same pathname, not reset to root.
I'm not sure why you would want to go to the root on refresh, but the way that you would accomplish that would be to manually navigate when your application is loading.
import { createBrowserHistory } from 'history'
const history = createBrowserHistory()
history.replace('/')
ReactDOM.render((
<Provider>
<ConnectedRouter history={history}>
...
</ConnectedRouter>
</Provider>
), holder)

Router.push() changes url but is caught in 404. Refresh same url works

I have a router something like this:
<Router history={browserHistory}>
<Route path="items">
<IndexRoute component={Items} />
<Route path=":id" component={ItemDetail} />
</Route>
<Route path="*" component={NotFound} />
</Router>
My Items component lists a bunch of items, each with a unique id.
The ItemDetail component... lets say just displays the props.params.id on screen.
When I click on an item, I call router.push('items/'+id) with the item's id.
The URL is updated correctly (e.g. */items/1234), yet it displays the NotFound component.
If I then press F5 (i.e. reload the same URL), it correctly displays the ItemDetail component.
Any idea why this is the case? The URL is the same for both.
(Note: If I change path=':id' to path='*' it goes to the correct page on router.push(), but I lose access to props.params.id, of course.)
(Note: If I change all the paths to use a / at the start, the navigation is very broken)
It appears that router.push() uses an absolute path (with a leading /) only.
Using the relative path as above caused the URL to update, but the router did not update so the page was not displayed. Pressing F5 caused the full route to be loaded, and therefore displayed the page.
Therefore I needed:
router.push('/items/'+id)

react-router v1.0.0 Cannot Reach Routes

I've been working with react-router for a project at work and for some reason It cannot reach routes besides the IndexRoute. When attempting to reach the /profile route it returns this in the browser:
Response In Browser
I'm trying to use react-router for client-side routing.
Heres my code for my routes:
let history = createBrowserHistory();
render((
<Router history={history} >
<Route path="/" component={App}>
<IndexRoute component={Landing}/>
<Route path="profile" component={UserProfile}/>
</Route>
</Router>
), document.getElementById('app'));
I thought it may have been the UserProfile component but when I plugged it into the IndexRoute it rendered properly. No errors show up in the console, I'm hoping the issue is something that is obvious that I overlooked, any and all help is welcome.