Reputation: 733
This problem is driving me insane, I got a simple little app created by create-react-app
and I am using React-Router
.
<Router>
<Route path="/pages/:pageId" component={Page} />
</Router>
In the Page component I have an fetch on componentDidMount
, its working as expected first time the route is loaded.
For example I visit: /pages/13
and then it fetches that pages data, but when I am on: /pages/13
and then click on a Link component (imported from React-Router
) redirecting me to: /pages/15
- the pageId
prop is then updated but it never re-renders.
The Page
component never run componentWillUnmount
before, or componentDidMount
after.
/pages/13
→ render()
→ componentDidMount()
→ render()
/pages/15
→ componentWillUnmount()
→ render()
→ componentDidMount()
→ render()
I am using the following versions:
What am I doing wrong? I am still pretty new to React so be nice :)
Upvotes: 3
Views: 3794
Reputation: 1296
Your problem is that componentDidMount
only executes when the component is completely mounted, and this only occurs one time. In this case, changing the route param doesn't change the component, I mean, you still being in the same component when you change the pageId
, thus the componentDidMount
is never executed again.
What could you do then?, well, I suggest you to look into componentWillReceiveProps(newProps)
method, this is executed whenever the component's props are about to be modified, which in this case, is what you are looking for, because, according to this:
You’ll have access match objects in various places: Route component as this.props.match; Route render as ({ match }) => (); Route children as ({ match }) => (); withRouter as this.props.match; matchPath as the return value;
the match object (which contains the route params) is given through component's props.
So, short answer. Use componentDidMount
for first time fetching, and then use componentWillRecieveProps(newProps)
for all the rest fetching calls.
check this for more info.
Note: I didn't know that componentWillRecieveProps(newProps)
was about to be somewhat deprecated, anyways, it suggest you to use getDerivedStateFromProps(nextProps, prevState)
which is basically the same
Upvotes: 3
Reputation: 2290
When parameter is changing, your Route
doesn't remount your component. This is an expected behaviour. You should catch the parameter changing via componentWillReceiveProps
, otherwise if you wish to force remounting, you should use <Route path="/your/path/with/:id" render={props => <Component {...props} key={props.params.id} />
Upvotes: 2