React Router V3 - Nested Route Component unmounts on path param change - javascript

I just noticed that in react router (v3.x) a component unmounts and remounts if a path param changes. Is this the expected behaviour?
Route:
<Route path="/landing/register/:step" component={Register}/>
Now, lets say I am on route "/landing/register/personal-data" and I am navigating via <Link/> or router.push({...}) to the next registration step "/landing/register/address", the Register-component gets first unmounted and then mounted again, loosing all its state.
Is this the correct way or am I doing something wrong?
EDIT:
It seems that the problem is that I am using nested routes, where I use a component for the parent route.
This example works (not re-mounting Register-Comp on path param change):
<Route path="/landing">
<Route path="register/:step" component={Register}></Route>
</Route>
But when I use a component for the parent route, it doesnt (not re-mounting AppView-Comp, but Register-Comp on path param change):
<Route path="/landing" component={AppView}>
<Route path="register/:step" component={Register}></Route>
</Route>

I solve this problem by nesting routes in child components, like this:
// Router class
<Route path="/landing/register" component={Register}/>
//Register component
<BrowserRouter>
<div>
<Route path="/landing/register/personal-data" component={PersonalData}/>
<Route path="/landing/register/payment-data" component={PaymentData}/>
...other routes
</div>
</BrowserRouter>
But in this case i store user data in redux store instead of component state, however you can store it on your component state it is not problem.

Related

How should I return HTML in a React.js class component without getting an error? [duplicate]

Matched leaf route at location "/" does not have an element. This means it will render an with a null value by default resulting in an "empty" page
//App.js File
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
// import ReactDOM from "react-dom";
const App = () => {
return (
<Router >
<Routes>
<Route path="/" component={ Home }></Route>
</Routes>
</Router>
)
}
export default App;
**My any react router related code not working i don't know why it happend when i start insert some route in program so it show this error **
In V6, you can't use the component prop anymore. It was replaced in favor of element:
<Route path="/" element={<Home />}></Route>
More info in the migration doc.
I had the same problem. Replace component with element and it worked.
Replace this:
<Route path="/" component={HomePage} exact />
with this:
<Route path="/" element={<HomePage/>} exact />
I had the same error however my fix was slightly different
I had spelled element wrong.
<Route exact path='/MyGames' elemtent={<MyGames/>}/>
and this was the error it gave me in the browser console
Matched leaf route at location "/MyGames" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.
Very simple:
use element instead of component
wrap the your component like this: {<Home/>} instead of {Home}
<Route path="/" component={ <Home/> } />
in version 6:
component replaced with element and needs to close "</Route>"
<Route exact path="/" element={<AddTutorial />}></Route>
https://reactrouter.com/docs/en/v6/getting-started/overview
This is a common problem if you are using react-router-dom V6
To solve this it's simple
In your code
Replace component with element
Replace {home} with {}
This becomes...
<Route path="/" element={}>
This will definitely solve the problem.
If you're using react-router-dom 6 or above, you may have a routes array that includes parent and child routes. You may then try to open a route such as
/portal
and get this error because that component corresponds to a child route
/:customerid/portal
but you haven't read your routes (and their child routes) closely enough to see that.

Matched leaf route at location "/" does not have an element

Matched leaf route at location "/" does not have an element. This means it will render an with a null value by default resulting in an "empty" page
//App.js File
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
// import ReactDOM from "react-dom";
const App = () => {
return (
<Router >
<Routes>
<Route path="/" component={ Home }></Route>
</Routes>
</Router>
)
}
export default App;
**My any react router related code not working i don't know why it happend when i start insert some route in program so it show this error **
In V6, you can't use the component prop anymore. It was replaced in favor of element:
<Route path="/" element={<Home />}></Route>
More info in the migration doc.
I had the same problem. Replace component with element and it worked.
Replace this:
<Route path="/" component={HomePage} exact />
with this:
<Route path="/" element={<HomePage/>} exact />
I had the same error however my fix was slightly different
I had spelled element wrong.
<Route exact path='/MyGames' elemtent={<MyGames/>}/>
and this was the error it gave me in the browser console
Matched leaf route at location "/MyGames" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.
Very simple:
use element instead of component
wrap the your component like this: {<Home/>} instead of {Home}
<Route path="/" component={ <Home/> } />
in version 6:
component replaced with element and needs to close "</Route>"
<Route exact path="/" element={<AddTutorial />}></Route>
https://reactrouter.com/docs/en/v6/getting-started/overview
This is a common problem if you are using react-router-dom V6
To solve this it's simple
In your code
Replace component with element
Replace {home} with {}
This becomes...
<Route path="/" element={}>
This will definitely solve the problem.
If you're using react-router-dom 6 or above, you may have a routes array that includes parent and child routes. You may then try to open a route such as
/portal
and get this error because that component corresponds to a child route
/:customerid/portal
but you haven't read your routes (and their child routes) closely enough to see that.

React Router re-render when using arrow function

I have App.js with route
<Route path="/home" component={() => <Home changeAuth={this.changeAuth} auth={auth} />}/>
But when i use component to display modal with:
<Link to="/home/info"> <span class="logout">App Info</span></Link>
<Route path="/home/info" component={Info} />
Component was re-render and run componentDidMount.
It's not when i use <Route component ={Home}/> but i want using props.
You should use Route render prop, not component in this case:
<Route path="/home" render={() => <Home changeAuth={this.changeAuth} auth={auth} />}/>
PS: this depends on the version of react-router that you are using, so I'm assuming you are using v4
From the Route Component Documentation:
When you use component (instead of render or children, below) the
router uses React.createElement to create a new React element from the
given component. That means if you provide an inline function to the
component prop, you would create a new component every render. This
results in the existing component unmounting and the new component
mounting instead of just updating the existing component. When using
an inline function for inline rendering, use the render or the
children prop (below).

react router this.props.location

I need a help with react-router v2+
I have to change class of navbar when route changed
for example for route /profile className will be "profile-header"
I tried to use this.props.location in navbar component but it shows undefined
Hope your help
Your navbar component (as you described it in your question) is probably not the route component, right? By route component I mean the one that you use in your react-router configuration that is loaded for a specific route.
this.props.location is accessible only on such route component, so you need to pass it down to your navbar.
Let's take an example:
Your router config:
<Router>
<Route path="/" component={App}>
// ...
</Router
Route component App:
class App extends React.Component{
// ...
render() {
return <Navbar location={this.props.location}/>
}
}
There could be a scenario where you may not have access to props.location to pass to the nav component.
Take for example - We had a header component in our project which was included in the routing switch to make it available to all routes.
<Switch>
<Fragment>
<Header/>
<Route path='..' component={...}/>
<Route path='..' component={...}/>
</Fragment>
</Switch>
In the above scenario there is no way to pass the location data to the Header component.
A better solution would be to us the withRouter HOC when a component is not being rendered by your router.
You will still have access to the router properties history, match and location when you wrap it in the withRouter HOC:
import { withRouter } from 'react-router-dom'
....
....
export default withRouter(ThisComponent)
react-router v4
From documentation:
<Route> component property should be used, when you have an existing component. <Route> render property takes an inline function, that returns html.
A <Route> with no path will always match.
Based on this, we can make a <Route> wrapper to any level of your html structure. It will always be displayed and have access to the location object.
As per your request, if a user comes to /profile page, the <header> will have profile-header class name.
<Router>
<Route render={({ location }) =>
<header className={location.pathname.replace(/\//g, '') + '-header'}>
// header content...
</header>
<div id="content"></div>
<footer></footer>
} />
</Router>
I couldn't solve it with the solutions given here and here is what worked for me:
I imported history into my component and assigned history.location.pathname to a variable which I later used for dynamic style manipulation.
In case you are rendering the component with pre-defined location.state values, first set your state with props.location.state then use your state data in your elements.

React Router, nesting routes after the params

So, I currently have the following as part of my url map for react.
<Route path="dog" component={DogWrapper}>
<Route path=":id" component={DogDetails}/>
<Route path=":id/genealogy" component={Genealogy}/>
</Route>
But I'm never hitting the Genealogy component. Any ideas as to why?
Your issue is with ordering. React-router works on precedence so it will always take the :id route first. Move the geneaolgy route up and you should be all set.
https://github.com/reactjs/react-router/blob/master/docs/guides/RouteMatching.md#precedence

Categories