Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
jharris4 opened this issue Mar 31, 2019 · 18 comments

Comments

@jharris4
Copy link
Contributor

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>

    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).
@jharris4 jharris4 changed the title react-router-config - tiny-invariant.esm.js:11 Uncaught Error: Invariant failed: You should not use <Switch> outside a <Router> react-router-config - Uncaught Error: Invariant failed: You should not use <Switch> outside a <Router> Mar 31, 2019
@jharris4 jharris4 changed the title react-router-config - Uncaught Error: Invariant failed: You should not use <Switch> outside a <Router> react-router-config - You should not use <Switch> outside a <Router> (it is inside a Router!) Mar 31, 2019
@jharris4
Copy link
Contributor Author

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... :-/

@jovinbm
Copy link

jovinbm commented Mar 31, 2019

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.

@jharris4
Copy link
Contributor Author

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...

@RachitKalra
Copy link

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 : ( ,

@maxolasersquad
Copy link

maxolasersquad commented May 14, 2019

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

@harri777
Copy link

Use connected-react-route

and

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

@cloudever
Copy link

The same issue when using StaticRouter in SSR

ximing added a commit to ximing/rab that referenced this issue May 31, 2019
@alex-my
Copy link

alex-my commented Jun 11, 2019

@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>

@njgraf512
Copy link

njgraf512 commented Jun 26, 2019

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?

@ryaninvents
Copy link

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 react-router-dom@5.0.0, and one for react-router-dom@5.0.1.

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.

@alerizzo
Copy link

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.

@alerizzo
Copy link

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.

@MeiKatz
Copy link
Contributor

MeiKatz commented Jul 24, 2019

@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.

@ryaninvents
Copy link

@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.

@alerizzo
Copy link

alerizzo commented Jul 24, 2019

@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...

@ryaninvents
Copy link

@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.

@wittlesouth
Copy link

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.

@raylyanway
Copy link

raylyanway commented Oct 20, 2019

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.

@lock lock bot locked as resolved and limited conversation to collaborators Dec 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests