Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-router doesn't remount component on different paths

I have a component 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 component and it checks on componentDidMount() 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 component. 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="/" component={this.LoginView}/>
          <LoginRoute exact path="/login" component={this.LoginView}/>
          <PrivateRoute exact path="/licensees/add" component={this.LicenseeForm}/>
          <PrivateRoute exact path="/licensees/:id/update" component={this.LicenseeForm}/>
          <Route path="*" component={this.NotFoundPage}/>
        </Switch>
      </Router>
    )
  }

const PrivateRoute = ({component: Component, ...rest}) => (
  <Route
    {...rest}
    render={props =>
      authService.checkIfAuthenticated() ? (<Component {...props} />) :
        (<Redirect
            to={{
              pathname: "/login",
              state: {from: props.location}
            }}/>
        )
    }
  />
);

Component:

componentDidMount() {
    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" component={this.LicenseeForm}/>
      <PrivateRoute exact path="/licensees/:Id/update" key="update" component={this.LicenseeForm}/>
like image 441
Xxtreem Avatar asked Jun 19 '18 14:06

Xxtreem


2 Answers

If you do need a component remount when route changes, you can pass a unique key to your component'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 component to unmount/remount.

like image 104
Piyush Zalani Avatar answered Nov 14 '22 21:11

Piyush Zalani


When the route is same and only path variable changes which in your case is "id", then the component at the top level of your route receives the change in componentWillReceiveProps.

componentWillReceiveProps(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 come on license page first time then save current Id in a variable. That only you will use in componentWillReceiveProps to detect change.

like image 22
Vikas Avatar answered Nov 14 '22 22:11

Vikas