Frank M
Frank M

Reputation: 533

React. How to redirect early in a component lifecycle

This seems so simple, but I am new to react and trying different approaches and nothing is working for me. (BTW I am a regular contributor but working on my clients machine and can't remember my so password.)

The version of react router is 4.0, and state is stored using redux.

The scenario is that we are changing the order of routing in our application and would like to redirect any users that have Urls with the old structure to the new Url structure. I have tried the following (also note that I have "scrubbed" the names of the page, function calls and variables):

  1. There is a trigger component for the section I need to direct from, with routing set up like this:

<Route path='page/:pageGuidGuid' component={PageTrigger}> </Route>

In the trigger component, ComponentWillMount makes a request that returns a 404 if the link is from the previous component, although it does redirect to the correct route. I am checking for and triggering the redirect in getInitialState, but the component keeps going through the lifecycle and ComponentWillMount is called, resulting in a 404 and then redirects to the correct page.

const PageTrigger = connectToStores(React.createClass({

getInitialState() {
    this.checkForRedirect();
    return {};
},

componentWillMount() {
    if (this.props.params.guid) {
        this.setCaseByGuid(this.props.params.guid);
    }
},
   checkFrorRedirect() {       
      /* logic to determine if it should redirect */      
      browserHistory.push(redirectUrl);
    }  
}

I have also tried creating a custom route...

<CaseRedirectRoute path='(cases/:caseGuid)' component={CaseTrigger}>

 </CaseRedirectRoute>

And in a separate module (based off a login sample)

const CaseRedirectRoute = ({ component: Component, ...rest }) => (
<Route
  {...rest} render={props => (
    checkForCaseRedirect(...props) ? (
        <Redirect to={{
            pathname: getCaseUrlRedirectUrl(...props),
            state: { from: props.location }
        }} />
    ) : (
        <Component {...props} />
    )
)} />

);

I have WithRouter imported from react router. When I try to run this I am getting an error inside the react framework:

Uncaught Type Error: Cannot read property 'createRouteFromReactElement' of undefined
  at RouteUtils.js:68
at forEachSingleChild (ReactChildren.js:52)
at traverseAllChildrenImpl (traverseAllChildren.js:98)
at traverseAllChildrenImpl (traverseAllChildren.js:114)
at traverseAllChildren (traverseAllChildren.js:186)
at Object.forEachChildren [as forEach] (ReactChildren.js:70)
at createRoutesFromReactChildren (RouteUtils.js:65)
at Function.createRouteFromReactElement (RouteUtils.js:35)
at RouteUtils.js:69
at forEachSingleChild (ReactChildren.js:52)

I've tried redirecting from app.js and page.js, but the PageTrigger is the first component having state set. I either need to figure out how to stop execution after the redirect, or figure out why my custom route keeps blowing up. Any help would be appreciated.

Upvotes: 0

Views: 1029

Answers (1)

Murilo Cruz
Murilo Cruz

Reputation: 2551

I'm not sure about your setup, but I would implement this redirect as this:

<Route path='oldurl/:p1/:p2' render={
  routeProps => (
    <Redirect to={'/newUrlHere/'+routeProps.match.params.p1} />
  )
}  />

So, if the route matches (you may specify exact match if necessary), when the Redirect "renders" it stops rendering and should start the rendering from the new URL. You may build your URL in the Redirect.to property as you wish

Upvotes: 1

Related Questions