react-router-config - You should not use <Switch> outside a <Router> (it is inside a Router!)

Created on 31 Mar 2019  路  18Comments  路  Source: ReactTraining/react-router

Version

5.0.0

Steps to reproduce

Use react-router-config with a static routes map

Expected Behaviour

It should work the same as in version 4.3.0

Actual Behaviour

Uncaught Error: Invariant failed: You should not use <Switch> outside a <Router>

The above error occurred in the <Context.Consumer> component: in Switch in Router (created by MyRoutes) in Provider (created by MyRoutes) in MyRoutes

Note from the component stack that my Switch is most definitely inside a Router.

I'm not sure if this issue may be specific to my use of react-router-config package, or that I'm wrapping the router in a redux Provider.

Also note that I have verified that no old instances of react-router 4.x are lingering around in my node_modules (I saw another issue suggesting that this might be causing this issue).

Most helpful comment

I had the same issue. This worked in v4.x but surprisingly broke in v5. My fix was to make sure that I imported everything from react-router-dom. Previously, I mixed between react-router and react-router-dom. According to this comment react-router-dom re-exports stuff from react-router. I think this deserves to be looked at more.

All 18 comments

I just tried to reproduce this on code sandbox and it works fine. So I'll close the issue.

General comment though, is that this new usage of rollup cjs/esm bundles is a fairly large disaster for people trying to use react-router.

I'd strongly recommend not using that approach if you want to be developer friendly... :-/

I had the same issue. This worked in v4.x but surprisingly broke in v5. My fix was to make sure that I imported everything from react-router-dom. Previously, I mixed between react-router and react-router-dom. According to this comment react-router-dom re-exports stuff from react-router. I think this deserves to be looked at more.

yeah, in my case it was related to the fact that I have a custom package that replaces react-router-config because they've been ignoring my PR for months, so I had to publish my fork to unblock.

Turns out I just had to fully publish my updated package and then it worked (after a couple of hours fighting to update my package to the new weird CJS vs ESM rollup builds).

I really wish they'd just keep the old-style es builds without all the rollup overhead, it'd be so much simpler...

I am getting the same issue was working fine on react router 4 , upgraded and it broke , however i only get this error when i build the app using webpack production mode : ( ,

I was using react-router-redux which is deprecated. Switching to connected-react-router resolved this problem for me.

Use connected-react-route

and

"react-router": "^4.3.1"
"react-router-dom": "^4.3.1"

The same issue when using StaticRouter in SSR

@jovinbm It's good job.

Invariant failed: You should not use <Switch> outside a <Router>
Invariant failed: You should not use <Link> outside a <Router>

Having the same issue in version 5.x when using a <Switch> inside a <StaticRouter> for server-side rendering. Had to downgrade to v4.3.0 to resolve. Reopen?

I had the same issue. I'd caused it myself, but here's an explanation in case someone else runs into the same problem.

We'd created a couple routes and published them internally in our package @org/components. Then, I tried to use these routes in @org/webapp. The versions for react-router and react-router-dom did not match exactly, so there were two different React.Context values: one for [email protected], and one for [email protected].

The solution: make the following changes to the @org/components codebase

  • Move react-router-dom and react-router from dependencies to devDependencies
  • Copy react-router-dom and react-router into peerDependencies
  • Republish

Now, there's only a single routing context, meaning the <Route> components can find their parent <Router> as intended.

I'm having this exact issue and none of these solutions or workarounds did anything for my situation. My scenario is the same as the one @ryaninvents mentions, but that solution didn't work for me either. I cleaned both node_modules folders and reinstalled every dependency on both projects with special care to version numbers and nothing.

Is there any way to check where routing context is being lost?? Components work fine in the library, and router works fine in the app. But if I want to use a component in the library that uses Link, NavLink, or any other router component, from the app, it fails. Context is always lost, and I have no clue what else to do.

Btw, if someone else stumbles upon this very same strange issue, I got tired of searching for a solution. I downgraded both react-router and react-router-dom to version 4.3.1 and now it works like a charm.

Don't bother losing time on this, and try again in a few months... or years.

@alerizzo Then you should stay on version 4.3.1 forever, because the way React Router uses the new context api is the way that React Context works: if you create two different context instances they will never be the same. The only thing we can do is, that we detect the parallel use of two different contexts and give a clearer notification about it.

@alerizzo are you using npm link? If so, even if the versions match you'll end up with two installations of react-router because dependencies are installed before the symlink is created.

If anyone else is using Yarn, has not linked their packages, and has this issue, it may be possible to fix this with the resolutions field. I'm not very familiar with Yarn though so can't be more specific in my advice.

@MeiKatz thanks! I used to have a similar issue with moment.js and with mobx, and I understand why this error happens. Maybe this is "not exactly the same use case" but, those two libraries solved the issue searching for an already created instance and use that instead. (But maybe, as we're talking about React context here... is totally different...)

@ryaninvents yep! I'm using npm link , but I don't understand why, because when I had this kind of issue with mobx or moment, it worked fine moving dependencies to peer and dev.

But, if that's the case.... how should I suppose to use any react router component inside my company's components library (without using npm link)? Publishing every time I make a change during development doesn't sound very friendly...

@alerizzo I have the same question! To be clear, I'm not affiliated with the React Router project at all... I'm just a developer who has learned a few strange lessons, most of them the hard way.

I'm trying to figure out the same workflow myself, and am considering writing a utility once I figure out a workflow that isn't completely horrible. What I've got in my head so far:

  • Organize your package so that all published code is contained in a single directory, such as /lib. In other words, package.json should specify something like "main": "lib/index.js" instead of "main": "index.js".
  • Run the build step for @org/component.
  • Use npm pack to generate a tarball of @org/component, then install this tarball in @org/webapp.
  • Inside webapp/node_modules, delete the @org/component/lib directory, and instead symlink the lib directory under your "component" workdir where your build output goes.
  • Now, any time you make source changes, they should get picked up by the consuming package. Unfortunately, if you update your dependencies or anything else about package.json, you need to go through the whole tarball song and dance again.

This is just a plan; I haven't had the need to test it yet.

Also having this issue after trying to npm link a package of components with a peer dependency on react-router-dom into another application. Not sure if this is react-router, npm link, or issues with react's new context APIs. The same code works when publishing the component package to a registry an installing it from there.

Maybe you should upgrade webpack to the latest version ? Previous version doesn't seem to understand the object spread syntax, which has been stable since node 8.
It helps me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

misterwilliam picture misterwilliam  路  3Comments

sarbbottam picture sarbbottam  路  3Comments

tomatau picture tomatau  路  3Comments

stnwk picture stnwk  路  3Comments

andrewpillar picture andrewpillar  路  3Comments