I have a ponent in my react app which is a form. The form is used to create new licenses OR edit existing licenses. Either way it is only one ponent and it checks on ponentDidMount() which "pageType" (add/update) it is. Now to my problem, when I'm using the form to edit a license (licensee/:id/edit) and I’m clicking the button which is bidet to create a new license (licensee/add), it will not remount the ponent. It will change the URL but all the preloaded data is still in the form.
LicenseeForm = Loadable({
loader: () => import('./license/LicenseeForm'),
loading: 'Loading..'
});
render() {
return (
<Router>
<Switch>
<LoginRoute exact path="/" ponent={this.LoginView}/>
<LoginRoute exact path="/login" ponent={this.LoginView}/>
<PrivateRoute exact path="/licensees/add" ponent={this.LicenseeForm}/>
<PrivateRoute exact path="/licensees/:id/update" ponent={this.LicenseeForm}/>
<Route path="*" ponent={this.NotFoundPage}/>
</Switch>
</Router>
)
}
const PrivateRoute = ({ponent: Component, ...rest}) => (
<Route
{...rest}
render={props =>
authService.checkIfAuthenticated() ? (<Component {...props} />) :
(<Redirect
to={{
pathname: "/login",
state: {from: props.location}
}}/>
)
}
/>
);
Component:
ponentDidMount() {
const locationParts = this.props.location.pathname.split('/');
if (locationParts[locationParts.length-1] === 'add') {
this.setState({pageType: 'add'});
} else if (locationParts[locationParts.length-1] === 'update') {
this.setState({pageType: 'update'});
...
}}
EDIT
This is how it works now:
<PrivateRoute exact path="/licensees/add" key="add" ponent={this.LicenseeForm}/>
<PrivateRoute exact path="/licensees/:Id/update" key="update" ponent={this.LicenseeForm}/>
I have a ponent in my react app which is a form. The form is used to create new licenses OR edit existing licenses. Either way it is only one ponent and it checks on ponentDidMount() which "pageType" (add/update) it is. Now to my problem, when I'm using the form to edit a license (licensee/:id/edit) and I’m clicking the button which is bidet to create a new license (licensee/add), it will not remount the ponent. It will change the URL but all the preloaded data is still in the form.
LicenseeForm = Loadable({
loader: () => import('./license/LicenseeForm'),
loading: 'Loading..'
});
render() {
return (
<Router>
<Switch>
<LoginRoute exact path="/" ponent={this.LoginView}/>
<LoginRoute exact path="/login" ponent={this.LoginView}/>
<PrivateRoute exact path="/licensees/add" ponent={this.LicenseeForm}/>
<PrivateRoute exact path="/licensees/:id/update" ponent={this.LicenseeForm}/>
<Route path="*" ponent={this.NotFoundPage}/>
</Switch>
</Router>
)
}
const PrivateRoute = ({ponent: Component, ...rest}) => (
<Route
{...rest}
render={props =>
authService.checkIfAuthenticated() ? (<Component {...props} />) :
(<Redirect
to={{
pathname: "/login",
state: {from: props.location}
}}/>
)
}
/>
);
Component:
ponentDidMount() {
const locationParts = this.props.location.pathname.split('/');
if (locationParts[locationParts.length-1] === 'add') {
this.setState({pageType: 'add'});
} else if (locationParts[locationParts.length-1] === 'update') {
this.setState({pageType: 'update'});
...
}}
EDIT
This is how it works now:
<PrivateRoute exact path="/licensees/add" key="add" ponent={this.LicenseeForm}/>
<PrivateRoute exact path="/licensees/:Id/update" key="update" ponent={this.LicenseeForm}/>
Share
Improve this question
edited Jun 22, 2018 at 8:09
Xxtreem
asked Jun 19, 2018 at 14:04
XxtreemXxtreem
1931 silver badge15 bronze badges
2
- 1 Due to the way react router and React works I think you are going to need to use shouldponentUpdate... github./ReactTraining/react-router/blob/master/packages/… – Gavin Thomas Commented Jun 19, 2018 at 14:19
- "When the location changes, the <UpdateBlocker> does not detect any prop or state changes, so its child ponents will not be re-rendered." – Gavin Thomas Commented Jun 19, 2018 at 14:21
3 Answers
Reset to default 15If you do need a ponent remount when route changes, you can pass a unique key to your ponent's key attribute (the key is associated with your path/route). So every time the route changes, the key will also change which triggers React ponent to unmount/remount.
When the route is same and only path variable changes which in your case is "id", then the ponent at the top level of your route receives the change in ponentWillReceiveProps.
ponentWillReceiveProps(nextProps) {
// In this case cdm is not called and only cwrp know
// that id has been changed so we have to updated our page as well
const newLicenseId = nextProps.match.params.id;
// Check id changed or not
if(currentLicenseId != newLicenseId) {
updateState(); // update state or reset state to initial state
}
}
I am pasting code which enables you to detect that page is changed and update the state or re-assign it to initial state. Also, suppose you e on license page first time then save current Id in a variable. That only you will use in ponentWillReceiveProps to detect change.
Use props 'render' instead ponent.
As per Doc Component props remount while parent state changes but render props update.
https://reacttraining./react-router/web/api/Route/route-render-methods