Reputation: 4617
What is the correct way to fetch data when switching route on same level?
Because, according to this, switching route on same level will
only call componentWillReceiveProps
and componentDidUpdate
.
And componentDidMount
is only called the first time route is entered.
With route configuration like this:
render((
<Provider store={store}>
<Router>
<Route path="/" component={App}>
<Route path="/:userId" component={Profile}/>
</Route>
</Router>
</Provider>
), document.getElementById('root'));
The Profile component is:
class Profile extends React.Component {
componentDidMount() {
// initial data
this.fetchUserData();
}
componentWillReceiveProps(nextProps) {
if (this.props.params.userId !== nextProps.params.userId) {
this.fetchUserData();
}
}
shouldComponentUpdate(nextProps) {
return this.props.params.userId !== nextProps.params.userId;
}
render() {
return (
<div className="profile"></div>
);
}
}
The data will be stored in application state field (props.userData
). But,
that's obviously will mess up with rendering cycle because route is
switched before fetch data is finished.
But, if I change to this:
// deepEqual is function to check object equality recursively
componentWillReceiveProps(nextProps) {
if (!deepEqual(this.props.userData, nextProps.userData)) {
this.fetchUserData();
}
}
shouldComponentUpdate(nextProps) {
return !deepEqual(this.props.userData, nextProps.userData);
}
This won't work because before userData
is fetched, those props is
deeply equal.
So, how to fetch data when switching route on same route level?
Upvotes: 2
Views: 2119
Reputation: 551
From the React Router docs:
componentDidMount () {
// fetch data initially in scenario 2 from above
this.fetchInvoice()
},
componentDidUpdate (prevProps) {
// respond to parameter change in scenario 3
let oldId = prevProps.params.invoiceId
let newId = this.props.params.invoiceId
if (newId !== oldId)
this.fetchInvoice()
},
When route changes this.props.params.userId
will update, which is caught in componentDidUpdate, and fires off a fetch. Of course this fetch will likely update state or props firing another re-render to show the fetched data.
Upvotes: 3