react-router: this.context.router is undefined

I just upgraded to react-router (and react) 0.13, and got rid of all the deprecated State mixins. Using this.context.router doesn’t seem to work. I just see this everywhere:

Uncaught TypeError: Cannot read property 'getParams' of undefined

Is there anything additional I need to do?


Edit by Ryan Florence to get people to the answer right here at the top of the issue 💃

Check out the upgrade guide: https://github.com/rackt/react-router/blob/master/UPGRADE_GUIDE.md#012x---013x

Sorry it wasn’t done w/ the release, it’s been an abnormally busy month for us since we quit our jobs and started a new business 😛

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 1
  • Comments: 94 (27 by maintainers)

Commits related to this issue

Most upvoted comments

Your class also needs

  contextTypes: {
    router: React.PropTypes.func.isRequired
  },

Using version 0.13.1 of react and react-router the following seems to work for me:

import React from 'react';
class LoginPage extends React.Component {
  ...
  onChange() {
    this.context.router.replaceWith('/');
  }
  ...
}

LoginPage.contextTypes = {
  router: React.PropTypes.func.isRequired
};

export default LoginPage;

react-router v2.0.0, you can try with:

ComponentName.contextTypes = {
  router: function () {
    return React.PropTypes.func.isRequired;
  }
};

If contextTypes is not defined, then this.context will be an empty object.

In general, I don’t like this switch to relying on context everywhere. I’d rather have a clear, well-defined API that I can use rather than rely on invisible magic that’s impossible to debug when it breaks. There’s no stacktrace, no actual error anywhere, and no trail leading to anywhere inside of react-router. It’s just… broken.

I was with react-router 0.13.x for now, so I just cut the BS with window.location.hash = ‘/newlocation’

Is the contextTypes changed to Object recently ! I was trying with

contextTypes: {
  router: React.PropTypes.func.isRequired,
}

Though working, threw warning!

Warning: Failed Context Types: Invalid context router of type object supplied to AddNew, expected function. Check the render method of RouterContext.

Changed to

contextTypes: {
  router: React.PropTypes.object.isRequired,
}

And everything it fine now !

I think the answer to the original question posted by @tjwebb is that the property “contextTypes” cannot be attached in the class declaration directly when using ES6. ES6 allows methods on the class declaration but not regular properties. To add the contextTypes property you would have to do this:

class ClassName extends React.Component{
    //... Add all your class method here
}
ClassName.contextTypes = {
    //....Add all your context types here
}

I was using this solution by @Flourad

ComponentName.contextTypes = {
  router: function () {
    return React.PropTypes.func.isRequired;
  }
}

And it worked fine. But then I created a new project and I got this weird error.

Now I’m using this:

MyComponent.contextTypes = {
    router: React.PropTypes.object
}

Which works and makes more sense since router is an object after all, and not a function.

Please use Stack Overflow or Reactiflux for questions – not the issue tracker.

Yes, so this works:

constructor(props, context) {
   super(props);
   console.log(context.router.getCurrentPathname()) //=> not undefined
}

example: http://learnreact.robbestad.com/#/articles/article/1 (check console.log)

@tjwebb My example above is using ES6, in which you cannot use mixins. You have to add the part

Page.contextTypes = {
  router: React.PropTypes.func.isRequired
};

after every class declaration in which you want to use this.context.router.

Keep using the mixins for now, we’re not super excited about this.context.router either.

I suggest removing the deprecation warning then, otherwise it might be confusing for users (like me 😉).

What do you think about injecting this.props.router to your handlers automatically?

Sounds good to me, although a bit cluttered, right now props really are the only way to safely pass stuff down the tree.