最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React-router doesn't remount component on different paths - Stack Overflow

programmeradmin5浏览0评论

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
Add a ment  | 

3 Answers 3

Reset to default 15

If 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

发布评论

评论列表(0)

  1. 暂无评论