简体   繁体   中英

Using the same component for different Routes with React Router

I have a PageBuilder component that dynamically builds edit/list pages according to a configuration file. I want to have dynamic routes (like "/collection/list", "/collection/edit/123123", "/dashboard", etc.) that use the same PageBuilder component.

I'm having trouble getting this to work - if I'm in "/collection/list" for example, when clicking on a link to "/collection/edit/1231" doesn't work. Only a refresh to that URL works (and vice-versa).

I tried putting my initialization code PageBuilder 's componentWilLReceiveProps but it seems to call it every second.

My routes look like this:

<Route path="/" component={App}>
  <IndexRedirect to="/dashboard" />
  <Route path="/:page/:collection/:action(/:entity_id)" component={PageBuilder}  />
  <Route path="/:page" component={PageBuilder} />
</Route>

And my PageBuilder:

constructor(props) {
    super(props);
    this.createSectionsHTML = this.createSectionsHTML.bind(this);
    this.onChange = this.onChange.bind(this);
    this.onSave = this.onSave.bind(this);
}

getPageName() {
    return this.props.params.page.replace(/-/g, '_').toLowerCase();
}

componentWillReceiveProps(props) {
    this.action = this.props.params.action;
}

componentWillMount() {
    let pageName = this.getPageName();
    this.props.dispatch(setInitialItem(pageName));
}

componentDidMount() {

    let pageName = this.getPageName();
    let { collection, entity_id } = this.props.params;

    if (collection && entity_id) {
        let { dispatch } = this.props;
        dispatch(getCollectionEntity(collection, entity_id, pageName));
    }
}

Any ideas of how to re-render the page each time I redirect to a different route?

It would be great if I could unmount and re-mount the component when redirecting, but I'm not sure how to go about telling React Router to do that....

Thanks!

Make this.state such that it will control how your component gets rendered.

Now, within componentWillReceiveProps , check the nextProps argument

componentWillReceiveProps(nextProps, nextState) {
  if( <check in nextProps if my route has changed> ) {
    let newState = Object.assign({}, this.state);
    // make necessary changes to the nextState Object by calling
    // functions which would change the rendering of the current page
    this.setState({ nextState });
  }
}

This would make componentWillReceiveProps take action only when the route changes.

Now in your render function,

render() {
  const { necessary, variables, to, render } = this.state;
  let renderVariables = this.utilityFunctionsReqToRender(someArgs);
  return (
    <toRenderJsx>
      ...
    </toRenderJsx>
  )
}

This would make your component "refresh" whenever the route changes.

componentWillReceiveProps is deprecated since React 16.3.0 (as says a warning in the browser console)

Reference : https://reactjs.org/docs/react-component.html#componentdidupdate

So componentDidUpdate can be used to get the new state and reload data depending on params

componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("componentDidUpdate " +prevState.id);
    reloadData(prevState.id);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM