Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

browserHistory.push doesn't navigate to new page

I've set up browserHistory on a router with this (react-router 2.0):

import { browserHistory } from 'react-router'

function requireAuth(nextState, replace) {
    if (!services.auth.loggedIn()) {
        replace({
            pathname: '/login',
            state: { nextPathname: nextState.location.pathname }
        })
    }
}

export default (store) => (
  <Router history={browserHistory}>
    <Route path='/' component={AppLayout}>
      <Route path="login" component={LoginContainer} />
      <Route path="map" component={MapContainer} onEnter={requireAuth} />
    </Route>
  </Router>
);

I'm then trying to use browserHistory in react-router to programmatically route to a new page from a view, ala:

 import { browserHistory } from 'react-router'

 ...

 browserHistory.push('/map');

This changes the URL to /map but does not render the components in that route. What am I doing wrong?

like image 908
outside2344 Avatar asked Feb 20 '16 17:02

outside2344


2 Answers

As mentioned in my comment I was having this same problem, but I've found a way to make it work.

What's happening here is your Route is changing, but your AppLayout component isn't actually updating it's state automatically. The Router doesn't seem to automatically force a state change on the component. Basically, this.state.children on your AppLayout is not being updated with the new children.

The solution that I found (and, full disclosure, I don't know if this is how you're supposed to achieve this, or if it's best practice) is to use the componentWillReceiveProps function and update this.state.children with the children from the new props:

componentWillReceiveProps(nextProps) {
    this.setState({
        children: nextProps.children
    });
}

Hope this helps!

like image 75
Magento Guy Avatar answered Nov 14 '22 00:11

Magento Guy


An alternative solution that allows the router to navigate to another section of your app without having to force an update via lifecycle method is using context router. All you need is to declare a contextType in your component (omitting router instantiation and other code for brevity):

class MyComp extends Component {
  static contextTypes = {
    router: PropTypes.object
  }

  handleClick = () => {
    this.context.router.push('/other/route')
  }
}

For reason(s) I'm not aware of, browserHistory.push() did not work for me, albeit browserHistory.goBack() and .goForward() did.

like image 2
flashmatrix Avatar answered Nov 14 '22 00:11

flashmatrix