1

I have been trying to solve a problem I've facing the last few days with routing a deep nested component. I am using reactjs v14.6 and react-router v2.0 with browserHistory. If I swap it out for hashHistory and use the deprecated history mixin it works as expected.

I have successfully rendered and able to route from default home page to profile page using react-router. I have a child component called searchGithub as my nav bar that is rendered on both home and profile components. Its a basic search that takes a query param profile/:username which successfully routes to the profile component/page. I followed the documents on swapping out the history mixing for higher order functions

Its when I try and use my search component on the profile page that I am experiencing problems. Its adding an additional /profile in the url. for example from the home page it will be properly route http://localhost:3000/profile/tyler but if I am on the profile page and try and search a username the url instead becomes http://localhost:3000/profile/profile/tyler causing an error Warning: [react-router] Location "/profile/profile/tyler" did not match any routes

here is my link to github repo to see full project

I don't think the problem lies in my browserHistory or on my server.js file rather a problem in either my routes file or in one of my components. Feel free to check out my link above to pull the full project and install dependencies if needed. I think it has to do with not passing in a location descriptor which I am not sure is the third argument that is needed to be passed too this.context.router.push()

here is my /App.jsx component

var React = require('react');
var ReactDom = require('react-dom');
var Router = require('react-router').Router;
var routes = require('./config/routes');
var browserHistory = require('react-router').browserHistory;

ReactDom.render(
  <Router history={browserHistory} routes={routes} />,
  document.getElementById('app')
);

here is my /routes.jsx

var React = require('react');
var Main = require('../components/Main');
var Home = require('../components/Home');
var Profile = require('../components/Profile');
var Router = require('react-router');
var Route = Router.Route;
var IndexRoute = Router.IndexRoute;

module.exports = (
  <Route path="/" component={Main}>
    <Route path="profile/:username" component={Profile} />
    <IndexRoute component={Home} />
  </Route>
);

here is my /SearchGithub.jsx

var React = require('react');
var Router = require('react-router');

var SearchGithub = React.createClass({
  contextTypes: {
    router: React.PropTypes.object.isRequired,
  },

  getRef: function(ref) {
    this.usernameRef = ref;
  },

  handleSubmit: function() {
    var username = this.usernameRef.value;
    this.usernameRef.value = '';
    this.context.router.push('profile/' + username, null);
  },

  render: function() {
    return (
      <div className="col-sm-12">
        <form onSubmit={this.handleSubmit}>
          <div className="form-group col-sm-7">
            <input type="text" className="form-control" ref={this.getRef} />
          </div>
          <div className="form-group col-sm-5">
            <button type="submit" className="btn btn-block btn-primary">Search Github</button>
          </div>
        </form>
      </div>
    );
  },
});

module.exports = SearchGithub;

here is my /main.jsx

var React = require('react');
var SearchGithub = require('./SearchGithub');

var Main = React.createClass({
  render: function() {
    return (
      <div className="main-container">
        <nav className="navbar navbar-default" role="navigation">
          <div className="col-sm-7 col-sm-offset-2" style={{ marginTop: 15 }}>
            <SearchGithub />
          </div>
        </nav>
        <div className="container">
          {this.props.children}
        </div>
      </div>
    );
  },
});

module.exports = Main;

I have a feeling it has to do with router.push({ pathname, query, state }) // new "location descriptor", hoping someone can help as I been pulling my hair out trying to figure out what I am doing wrong. I am also curious how I would implement location descriptor if that is in fact what is causing my problem

4

1 回答 1

3

Helped you out on discord, but I'll post it here as well.

Currently react-router + history do not work well together for relative transitions. See the relevant github issue here - https://github.com/rackt/history/issues/135.

Also you should either pass a pathname only to the router or a location descriptor which is a single object.

 this.context.router.push('/profile/' + username);

or

this.context.router.push({ pathname: '/profile/' + username });

Note the leading /

于 2016-02-05T22:51:27.343 回答