I have a React route like code below:
<Route path='/settings' component={Settings} />
And inside Settings component, it has 3 nested routes:
<Route path='/settings/general' component={GeneralSetting} />
<Route path='/settings/team' component={TeamSetting} />
<Route path='/settings/email' component={EmailSetting} />
So my question is how can I get the nested pathname at most right position (such as '/general', '/email') only without the parent route ('/settings'). Currently, I'm using string splitter on location pathname (/settings/general) to achieve this. Are there any best practice for this situation?
I appreciate any help. Thanks in advance.
IMO, there are no best practice to get child path in react router. You are using string splitter on location which is fine though.
If you still need to get child path only you can use params in url instead and render component on based of params like below
<Route path='/settings/:type' component={Type} />
In Type (new component to render child) component you can get params like below
this.props.match.params.type
that will give you general , team and email value based on your url.
Related
I'm trying to create an independent Route (not sure if that's the correct term) at BulletinBoard.js where I can use Link to go to Create Bulletin component.
I'm also trying to create another independent Route at BulletinList.js where I can navigate to Edit Bulletin with their respective IDs.
Before this, I tried using useRouteMatch with path and url, but apparently that wasn't the correct way to do it, now I'm told to use useLocation, it does adds the /createbulletin and /editbulletin/id paths behind the current URL, but it doesn't navigate to the component itself.
I've been cracking my head over this for the past 2 days and I still haven't figured out the correct way to do this.
Here is the codesandbox that I've created for reference.
The reason your code didnt navigate to a different component after the url changed is because you didnt use the exact attribute when declaring the route. So its matching /bulletinboard/anything and then it always renders de BulletinBoard component.
You could define all routes at the App.js file like
<Switch>
<Route path="/" component={Home} exact />
<Route path="/bulletinboard" component={BulletinBoard} exact />
<Route path="/bulletinboard/edit/:id" component={EditBulletinBoard} exact />
<Route path="/infohub" component={InfoHub} exact />
<Route component={NotFound} />
</Switch>
Also, check out the useHistory hook
So at the BulletinBoard.js when the user clicks the link
onClick={() => history.push(`/bulletinboard/edit/${id}`)}
Note that the edit route renders a different component that your codesandbox didn't have yet
In my parent App.js file I have :
<Route path="/login" component={Login} onFormSubmit={this.onLoginSubmit} />
But in Login.js when I do :
this.props.onFormSubmit(this.state.email, this.state.password);
I get : TypeError: this.props.onFormSubmit is not a function
EDIT : I see that this is a workaround :
<Route path="/login" render={(props) => (<Login onFormSubmit={this.onLoginSubmit} {...props} />)} />
Or this the only / right way to get this working like this ?
You should use render props like this.
<Route
path='/login'
render={(props) => (
<Login onFormSubmit={this.onLoginSubmit} />
)}
/>
I am assuming that you are using react-router-dom here. In that case, the Route component injects only three properties to the component property, Login.
You may refer to https://reactrouter.com/web/api/Route/route-props, but basically only the following values will be exposed (i.e. injected) by Route to the Login component:
match
A match object contains information about how a matched the URL
location
Locations represent where the app is now, where you want it to go, or even where it was
history
The term “history” and "history object" in this documentation refers to the history package, which is one of only 2 major dependencies of React Router (besides React itself), and which provides several different implementations for managing session history in JavaScript in various environments
Hence, passing an arbitrary property value like onFormSubmit will not work since Route does not inject it into the child component. That's the reason why you're getting the TypeError. If you really need to expose this.onLoginSubmit, I suggest you use React context, aside from the answer by Nilesh that uses render props.
I'm using React router and i would like to be able to send links or share it but everytime i realload the page, the state is becoming empty
http://localhost:3000/project/element=7/userid=9/exercises
If i enter this query in the url the state will not be preserved.
Here is my code:
<Route
exact
path="/project/element=:elementId/userid=:userid/exercises"
component={Exercises}
key={`exercises-id`}
/>
I tried to:
<Link to="/project/element=:elementId/userid=:userid/exercises" query={this.props.query}
But it's not preservering the state of my userId and elementId.
Here is the route:
<Route
exact
path="/project/element=:elementId/userid=:userid/exercises"
component={Exercises}
key={`exercises-id`}
/>
Thanks for the help
path="/project/element=:elementId/userid=:userid/exercises"
Should be
path="/project/element/:elementId/userid/:userid/exercises"
inside
Let's say I have these routes:
<Route
path="/subpage/:slug"
component={SubPageDetail}
key="subpage-detail"
/>
<Route
path="/subpage"
component={SubPage}
key="subpage"
/>
For the :slug, we have certain pages that have a match e.g. /subpage/subpage-info1. However, if someone types gibberish as in: /subpage/fhfjadsf33, which doesn't exist, we want to redirect that user to the immediate parent which is /subpage (not the homepage or anything).
How do we achieve that in react-router?
All you have to do, is to add this route
<Route component = { ComponentError } />
Of corse, you have to create the ComponentError to show your page error or whatever you want.
But still, you will have a problem, the ComponentError will alwasye show in every page, to adjust this, you have to wrape your routes inside a switch tag like this.
import { Switch } from "react-router-dom"
...
...
<Switch>
<Route path="/subpage" component={SubPage} />
<Route component = { ComponentError } />
</Switch>
Of corse I would like to clarify that it is available on react Router V4.
Hope it will help.
Sorry I forgot to mention, that all you have to do, I think is to change this CompoenentError with your component subPage.
Like this, it will help you, and help others that want to achieve athores goal with that method
You have two options. Either you let react-router check if the route has been defined and if not, redirects the user to a default component. Or you can have logic in your code to check the url. I think the first option is the easiest.
Just add a route like so :
<Route path='*' exact={true} component={MyDefaultComponent} />
I'm struggling to do anything with react/redux.
One of my last challenges was to pass some data from Child Component to Parent Component. I couldn't get the child props by calling parentComponent.props.children.props (I also tried converting children to Array with React.Children.toArray) and then I found a solution for my specific problem reading some data that comes with React Router.
I managed to find out the child component by calling this.props.location.pathname in Parent Component.
I have a Routing structure as following
<Router history={history}>
<Route path="/main" component={Main}>
<Route path="something" component={Something} />
</Route>
</Router>
I wonder if it is possible to pass some data to Main in this declaration. Something like:
<Route path="something" component={Something} data={foo: 'myData'} />
And get foo in the Main.render
Is there something close to this?
You could pass 'myData' as a query parameter. This is my personal preference for passing props to a component using React Router. Then when you browse to /main/something?foo=myData, you can access foo from this.props.location.query.foo.
Any props you pass to the route definition is accessible under the route node in the props. In your Something component, should be able to get the data prop with this.props.route.data