2
votes

I am working on a React app that is 'remote controlled' and am trying to connect the app's tab navigation via Pusher. I am using react-router-dom and have set up my connection to Pusher and the channels it listens to in the componentDidMount. I need to have the app change URL navigation each time a message is returned but cannot figure out what the correct way to 'push' it is. I have google many threads about programmatically navigating react-router-dom and have tried this.history.push(), this.props.history.push() and it's always throwing an error that history is undefined. The listeners reside in the same Component as the routing itself.

    import React, { Component } from 'react';
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    import axios from 'axios';
    import Pusher from 'pusher-js';

    import Component1 from './Component1';
    import Component2 from './Component2';

    export default class AppRouter extends Component{

    componentDidMount() {
          const pusher = new Pusher('8675309', { cluster: 'us2', encrypted: true });
          const nav_channel = pusher.subscribe('nav');
          nav_channel.bind('message', data => { this.props.history.push(data.message) });
    }

...

render(){
    return(
      <Router>
        <Switch>
          <Route path='/path1' render={() => <Component1 navigate={this.handleNavChange} />} />
          <Route path="/path2" render={() => <Component2 navigate={this.handleNavChange} />} />

        </Switch>
      </Router>
    )
  }

    }

I need the app to change the URL or the routing each time the message is received from another connected app but I cannot figure out how to make react-router-dom (v4) do it within the same component as the Router itself. Any information or pointing me to a resource would be highly appreciated.

2

2 Answers

4
votes

You need to use the withRouter decorator from React-Router to get access to match, location, and history.

import { withRouter } from 'react-router'

Wrap your component when exporting

export default withRouter(yourComponent)

Then you will have access to history from props.

https://reacttraining.com/react-router/core/api/withRouter

2
votes

To add on to andrewgi's answer:

After using withRouter() on your component, OR a parent component, try the following code in your component:

static contextTypes = {
    router: PropTypes.object,
    location: PropTypes.object
}

These should be defined, you can try console.log(this.context.router, this.context.location)

Then, to navigate programmatically, call

this.context.router.history.push('/someRoute');

Note: the context API is not stable. See Programmatically navigate using react router and https://reactjs.org/docs/context.html#why-not-to-use-context.