Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redirect. #92

Open
chrisdew opened this issue Oct 15, 2014 · 14 comments
Open

Redirect. #92

chrisdew opened this issue Oct 15, 2014 · 14 comments

Comments

@chrisdew
Copy link

I'm looking for react-router-component's equivalent of https://github.com/rackt/react-router 's <Redirect ...>.

If there isn't one, how do most users of react-router-component currently do their redirects?

@STRML
Copy link
Owner

STRML commented Oct 15, 2014

We don't have a declarative way to do this currently, the manual way to do this would be to insert a fallback route in a hierarchy and fire a new route based on the current location.

Do you mind if I ask what your use case is?

@chrisdew
Copy link
Author

Do you think <redirect ...> should be a feature of react-router-component?

Is there an architectural reason why it hasn't been implemented, or is it a matter of time and priorities?

@chrisdew
Copy link
Author

I have an application with several pages which are peers - i.e. /foo, /bar, /baz and /quuz.

I want the root route / to be redirected to /baz so that when we change the default page, user's /baz bookmarks will still work.

If we used BazPage as the handler for /, users' bookmarks would break when we changed the default page.

@STRML
Copy link
Owner

STRML commented Oct 15, 2014

I see. That makes sense to me. It is just a matter of time and priorities. I think it should be rather simple to create a component that reads the current URL on mount, reaches out to its parent router and reroutes. Would be very happy to accept a PR.
On Oct 15, 2014, at 5:37 PM, Chris Dew notifications@github.com wrote:

I have an application with several pages which are peers - i.e. /foo, /bar, /baz and /quuz.

I want the root route / to be directed to /baz so that when we change the default page, user's /baz bookmarks still work.

If we used BazPage as the handler for /, users' bookmarks would break when we changed the default page.


Reply to this email directly or view it on GitHub.

@chrisdew
Copy link
Author

Just posting my interim solution, in case it helps anyone.

function createRedirect(url) {
  return React.createClass({
    mixins: [NavigatableMixin],

    componentDidMount: function () {
      console.log('redirecting to', url);
      return this.navigate(url);
    },

    render: function () {
      return <p>redirecting to <a href={url}>{url}</a></p>;
    }
  });
}

    <Pages className="App" path={this.props.path}>
      <Page path="/" handler={DashboardPage} />
      ...
      <Page path="/commissioning" handler={this.state.logged_in ? CommissioningPage : createRedirect("/login")}/>
      <Page path="/login" handler={LoginPage}/>
      <NotFound handler={NotFoundHandler} />
    </Pages>

Note: This is only "mostly" functional. If for some reason if you request the redirected page directly (i.e. by typing in the URL), then it change the page location, but will display the blue link instead of showing the content of the new page. I have no idea why this is.

@jbach
Copy link

jbach commented Jan 1, 2015

@chrisdew Have you found a solution to this particular problem yet? I face the same problem, page location being correct, but showing the wrong component.

@MandarinConLaBarba
Copy link

@STRML I've started to work on this but I suspect I'm going about this in the wrong way.

I've gotten the following scenario to work:

/some/path -> /another/path

But when interpolation is involved, the redirect takes the literal path template (not interpolated):

/user/1234 -> /user/:userId/home //where path={"/user/:userId"} and redirectPath={"/user/:userId/home"}

The relevant code here:

https://github.com/MandarinConLaBarba/react-router-component/blob/issue-92-redirect/lib/Route.js#L30-L59

Thoughts?

@pospi
Copy link

pospi commented May 26, 2015

Not sure if I am abusing navigate(), but I am trying to use this same approach from componentWillMount() in order to create authentication mixins and I have the same issue there with the new route not being rendered in response to the redirect.

@jsg2021
Copy link
Contributor

jsg2021 commented May 28, 2015

In my application this component handles redirects by just <Redirect path={newPath}/>

import React from 'react';
import Router from 'react-router-component';
import Loading from 'common/components/Loading';

export default React.createClass({
    displayName: 'Redirect',
    mixins: [Router.NavigatableMixin],

    propTypes: {
        force: React.PropTypes.bool,
        location: React.PropTypes.string
    },

    performRedirect (props) {
        let loc = props.location;
        let location = global.location;
        let currentFragment = location && location.hash;

        if (props.force) {
            console.debug('Forceful redirect to: %s', loc);
            return location.replace(loc);
        }

        if (loc && loc.indexOf('#') === -1 && currentFragment) {
            loc = loc +
                    (currentFragment.charAt(0) !== '#' ? '#' : '') +
                    currentFragment;
        }


        // let routes = this.context.router.props.children.map(x=>x.props.path || 'default');
        // console.debug('Redirecting to %s, routes: %o', loc, routes);
        console.debug('Redirecting to %s', loc);
        this.navigate(loc, {replace: true});
    },


    startRedirect(p) {
        clearTimeout(this.pendingRedirect);
        this.pendingRedirect = setTimeout(()=> this.performRedirect(p), 1);
    },


    componentDidMount () {
        this.startRedirect(this.props);
    },


    componentWillReceiveProps (props) {
        this.startRedirect(props);
    },


    render () {
        return (<Loading message="Redirecting..."/>);
    }
});

@pospi
Copy link

pospi commented Jun 5, 2015

Works for me; I ended up taking your code and turning it into a mixin that wraps NavigatableMixin. The key component is the setTimeout(), so long as you call .navigate() outside of the React render loop the router will re-render the page correctly. Seems like a workaround for a bug within the framework but certainly works well enough for now.

@saidimu
Copy link

saidimu commented Aug 26, 2015

For a related redirect issue #24 (comment), here's what I use that so far works even when directly typing the url:

https://gist.github.com/saidimu/2758402f7916f4e35dee

// jshint unused:true
var React = require('react');

var NavigatableMixin = require('react-router-component').NavigatableMixin;

var Redirect = React.createClass({
  mixins: [NavigatableMixin],

  _redirect: function(url) {
    this.navigate(url);
  },

  propTypes: {
    url: React.PropTypes.string.isRequired,
  },

  componentDidMount: function() {
    console.log('Redirecting to %s: ', this.props.url);
    this._redirect(this.props.url);
  },

  render: function() {
    return null;
  }
});//Redirect

module.exports = Redirect;

@chrisdew @jbach I wonder if the issue you faced is because of not rendering null?

@jsg2021
Copy link
Contributor

jsg2021 commented Aug 26, 2015

@saidimu Redirects replace the current route... you should add {replace: true} as the second argument to navigate

@saidimu
Copy link

saidimu commented Aug 27, 2015

@jsg2021 Where is the replace parameter documented? I see no appreciable difference between omitting it, {replace: true} and {replace:false}

@jsg2021
Copy link
Contributor

jsg2021 commented Aug 27, 2015

@saidimu It's not documented. Its internal implementation. You are calling parts of the router that were not meant to be exposed. (much like context in React) See this line.

The only difference will be your history in the browser will not include the route the redirect was on...
ex:

if /foo/bar renders a redirect to /foo/baz, when you arrive at /foo/baz hitting the back button will take you to the page before you got to /foo/bar because the redirect replaces that entry in the history.

The Redirect component I shared above is a complete example that is heavily used in my company's application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants