Pavel Poberezhnyi
Pavel Poberezhnyi

Reputation: 773

React-router. Missing router as context in component

I use react-router v4 and i would like to programatically navigate to other url (i often need this in my stores). In react-router v3 it was so easy: u have only to use browserHistory.push(). But this time it's complicated. I can't use as pointed here out of any react component. So, i try to get router from context. Here is my component

'use strict';
import React, { Component } from 'react';
import { observer, Provider } from 'mobx-react';
import { BrowserRouter, Match, Miss, Link } from 'react-router';
import axios from 'axios';
import Main_Store from '../main.store';
import Signin from '../../auth/components/signin.component';
import Signup from '../../auth/components/signup.component';
import Header from './header/header.component';
import Zone from '../../zone/components/zone.component';

const main_store = new Main_Store();

@observer
class Base extends Component {
   render() {
      const get_base = (props) => {
         return (
            <Provider main_store={main_store} profile={main_store.profile}>
               <div>
                  <Header main_store={main_store} />
                  <main>
                     <Match pattern={'/*/zone-**'} component={Zone} />
                     <Match pattern={'/*/signin'} component={Signin} />
                     <Match pattern={'/*/signup'} component={Signup} />
                  </main>
               </div>
            </Provider>
         )
      };
      return (
         <BrowserRouter>
            <Match pattern="/:view_type" render={(props) => get_base(props)} />
         </BrowserRouter>
      );
   }
   constructor(props) {
      super(props);
   }
}

Base.contextTypes = {
  router: React.PropTypes.object
};

export default Base;

and my zone component which also want to have access to router

'use strict';
import React, { Component } from 'react';
import { observer } from 'mobx-react';
import { BrowserRouter, Match, Miss, Link } from 'react-router';

@observer(['main_store'])
class Zone extends Component {
   render() {
      const { main_store } = this.props;
      return (
         <div>
            Zone component
         </div>
      );
   }
   constructor(props) {
      super(props);
   }
   componentDidMount() {
      console.log('this Zone', this)
   }
}

Zone.contextTypes = {
   router: React.PropTypes.object,
   history: React.PropTypes.object
}

export default Zone;

but there is nothing. Router is undefined. What did i do wrong? Any other ideas how to programmatically navigate out of component?

Upvotes: 0

Views: 817

Answers (1)

Paul S
Paul S

Reputation: 36787

You will only be able to access context.router through children of your <BrowserRouter> component. Because <Base> is a parent of your <BrowserRouter>, you cannot access context.router through it. If you move your <BrowserRouter> up a level (outside of the <Base>), your code should work.

ReactDOM.render((
  <BrowserRouter>
    <Base />
  </BrowserRouter>
), holder)

Upvotes: 1

Related Questions