7

I'm having a problem with react-router-component. I'm trying to make a redirect library that does a "soft" redirect (equivalent to clicking a link, as opposed to window.location = ...) that I can require from a .jsx component.

Per the docs I should just be able to call router.navigate(path) to redirect.

When, for example, I call this on page A, the url in the address bar changes to page B as desired. However, page A simply reloads, leaving the address bar as page B and the display as page A. Suggestions?

Logan Howard
  • 212
  • 1
  • 3
  • 11

4 Answers4

8

You should be able to solve this using the Navigation mixin.

Then you can use this.transitionTo with the name of your page.

var PageAdd = React.createClass({

    mixins : [Router.Navigation],

    handleSubmit : function(e) {
        e.preventDefault();

        this.transitionTo('pages');

    },

    render: function () {
        return (
            <form onSubmit={this.handleSubmit}>
                <button type="submit" className="btn btn-default">Submit</button>
            </form>
        );
    }
});

Read more: https://github.com/rackt/react-router/blob/master/docs/api/mixins/Navigation.md

Machiel
  • 1,495
  • 12
  • 15
2

We ended up doing a hacky solution: calling the following when a redirect should happen, where path is something like /questions/23.

// call an event to get the router from somewhere else that's listening
// to this event specifically to provide the router
document.dispatchEvent(new CustomEvent('router.get', {
  detail: {
    callback: function(router) {
      router.navigate(path);
    }
  }
}));

Then, in the router, the event listener:

var App = React.createClass({
  listenForRouter: function listenForRouter () {

    var self = this;
    document.addEventListener('router.get', function(e) {
      setTimeout(function() {
        e.detail.callback(self
                          .refs.router
                          .refs.locations);
      }, 1);
    });
  },

  componentDidMount: function componentDidMount () {
    this.listenForRouter();
  },

  // additional lifecycle methods
});
Logan Howard
  • 212
  • 1
  • 3
  • 11
1

Not sure if this really answers the question, and an answer has already been accepted but I would use link from react-router:

in the routes you define names (this from a music database page:

var routes = (
    <Route name="app" path="/" handler={require('./components/app')}>
        <DefaultRoute handler={require('./components/homePage')}/>
        <Route name="artist" handler={require('./components/artist/artistsPage')}/>
        <Route name="artistSearch" path="artist/:artistSearchName" handler={require('./components/artist/artistsPage')}/>
        <Route name="artistSearchPage" handler={require('./components/artist/manageArtistSearchPage')}/>
        <Route name="album" handler={require('./components/album/albumsPage')}/>
        <Route name="searchAlbums" path="album/:artistId" handler={require('./components/album/albumsPage')}/>
        <Route name="song" handler={require('./components/song/songsPage')}/>
        <NotFoundRoute handler={require('./components/pageNotFound')}/>
    </Route>
);

and then in your component import Link from React-router:

var Link = require('react-router').Link; //(ES5)
import {link as Link} from 'react-router'; //(ES6)

and then you can use as the tag and it will work like an a tag with href = "something"

    <div>
        <h1>Artist Search Page</h1>
        <ArtistSearchForm
            artistName={this.state.artistName}
            onChange={this.onArtistChangeHandler}
        />
        <br/>
        <Link to="artistSearch" params={{artistSearchName: this.state.artistName}} className="btn btn-default">Search</Link>
    </div>

I also used it in a list to make the artist name a link to there albums page.

bkane56
  • 1,669
  • 1
  • 12
  • 17
0

This is not well-documented, but it is possible to perform a soft redirect using the navigate(path) method of the environment.defaultEnvironment object.

import {environment} from 'react-router-component'
...

environment.defaultEnvironment.navigate("/");

This doesn't take into account the current routing context though, so it won't allow you to redirect to paths relative to inner routers. For an approach that respects the routing context, see NavigatableMixin. Mixins are not an option for my solution, since I'm using ES6 classes, but the implementation could be copied from there.

Adam Brown
  • 1,056
  • 10
  • 13