3

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!

2 Answers 2

9

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! The way my PageBuilder works doesn't really rely on this.state but I may change it so that it does (I'm using Redux for my app-wide state). Another problem I've run into with this approach is that I know when my location changes, but if I were to refresh the page, I have no way of knowing that I "changed" route (since nextProps and this.props are apparently identical...) But I will try playing around with this solution, I think this is a good starting point. Thanks!
Cool, I got this to work (well, there are some minor issues, but the routing works!) by changing render to rely more on this.state. Thanks!
1

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.