-
Notifications
You must be signed in to change notification settings - Fork 47.6k
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
Warn when two versions of React are used alongside #2402
Comments
There's probably no good way to find out if two copies of React are loaded (CommonJS modules are the antithesis of sharing a global scope, they're literally two duplicate but separate modules). But I would expect React to be clever enough to figure out that, say, a component is a React component even if it's not from the same copy of React. |
I think it's lesser evil to put some flag on |
@sebmarkbage @zpao |
I think that in the future, this will actually just work. In the meantime we can warn here: https://github.com/facebook/react/blob/master/src/core/ReactElement.js#L230 |
Would it catch all of the issues listed above though? Usually the problem comes up when some component or helper library loads its own version. Will we get to Besides, does React truly support independent Reacts on page right now? Do they not interfere in any way at all if they aren't mixed (e.g. browser event handling)? |
(To clarify, I was referring to @syranide'a comment) |
I might be mistaken, but ignoring weird hacks then the only issue with multiple instances of React are when ReactElements from different instances gets mixed up. Depending on which API you feed them to, you're going to see lots of different errors though. So yeah... I think that should take care of all, or most at the very least.
As long as you never stop event propagation or mount them inside each other it should be OK I think (but still not great though).
Good point. |
Just a confirmation from someone who just flushed 3 hours of debugging time down the toilet that, yes, this issue is hard to debug, please make at least a warning. |
We should already be warning in the case that an element from one copy of React is passed to React.render in another: react/src/browser/ui/ReactMount.js Line 363 in d75512f
I guess the cases here are when nesting elements from different versions inside each other? |
Yes. At least it was in my case. Nested elements created from different React versions. |
Removing react dep to fix issue where multiple react versions would load.
Just my 2cents: I had the same issue today and my problem was using browserify 8.1.3 instead of 8.1.1 Hope it helps |
The other issue with this is you can't reliably use the dependency injection mechanism, e.g. to change the batching strategy, while using components from multiple modules where each has it's own instance of React as a dependency. Even if they are the same version of React. |
+1 ; thanks gaearon |
@charypar said: "The other issue with this is you can't reliably use the dependency injection mechanism, e.g. to change the batching strategy, while using components from multiple modules where each has it's own instance of React as a dependency. Even if they are the same version of React." This. |
The main workaround many modular React components are using is to specify React as a |
I've seen this a lot as well, and had lots of requests to switch React to a The most common frustration I've seen is when npm subtly installs two versions of React, and Browserify (correctly) includes both in the build. It can happen unexpectedly w/ package updates and breakage ensues. A warning from React that "hey, there is more than one of me on the page" seems like the most elegant way to warn developers early and direct them to an explanation of what's gone wrong / how to fix it. It's a side-effect of npm's dependency rules and node's
... there's a good argument to be made that this isn't React's problem to solve, but since it's a common problem and React can solve it, I think it would be great if it did. |
@JedWatson A solution I found with browserify: {
dev: {
files: {
'public/app.js': ['react/index.jsx']
},
options: {
alias: [
"react:react", "React:react"
],
transform: [babelify,reactify]
}
}
}, so it isn't impossible to fix, but I'd make the argument that since this is such a common issue it needs to be highlighted more clearly in the React docs. |
@spicyj when using browserify it can happen just when requiring two different versions of React because of the way it handles deduplication. Requires with the same path and code between the two versions can end up getting de-duped. Modules where the code/require path was changed between versions get deduplicated and others don't. So I encountered this:
As long as modules can be stateful, this approach to deduplication seems horrifically unsafe. I'll file an issue with Browserify itself, I haven't yet verified if Webpack would have the same issue. Either way - I think it would make sense to handle it specifically in React given how it can trip newcomers up. |
This causes a variety of hard-to-debug issues. See facebook#2402 for examples. Fixes facebook#2402
same issue with webpack and react.js loading manually. |
@gaearon @spicyj Is it still an issue to load more than one version of React on a page, even if those instances are managing totally separate DOM trees and aren't being explicitly instantiated as globals? Like if, say, I had a package with |
@mnquintana No, that should work now if both are on a recent version of React. |
Could you please point me out what would be the behavior of React if , let say , we want to introduce a widget including React in a host page that has an older version of it and the possible workaround to make it work? |
Old versions of React are probably only tripped up by data-reactid IDs in the DOM that it didn't generate. If you're doing only client-side rendering with your widget, it should only have a data-reactroot attribute and no data-reactid so there shouldn't be any conflict. |
Just ran into problems again today when I accidentally had 16.4.2 and 16.5.0 installed in a project, no warning from React. To make matters worse, the duplicate versions were caused by a bug in |
Was there any resolution as to whether or not this is possible and/or a good idea? It seems like it'd provide developers with useful information. |
Project A uses React 16 wherein Project B uses React 15, Lets say Project A is package got used in Project B - can that work? |
Would Preact and React have the same issue described here? I’m asking because I’m using single-spa for a platform play at a large company of distributed teams. |
It sounds to me like there are two separate issues here:
I don't know about the status with modern versions of React. In the case of Preact (1) should be fine but since it does have some global state you could run into problems in situation (2). Please file an issue in the Preact repository if you'd like to discuss further. |
This appears to be a bad link. |
For someone encountering this at the moment - does anyone have any tips on identifying the cause and debugging the issue? I've used the check from the hooks page (how I discovered this) which confirms I've got 2 instances loaded:
I believe I'm doing things by the book, in a monorepo react, react-dom etc are all always |
People lose hours of work debugging a simple issue: two versions of React being loaded at the same time.
gaearon/react-hot-loader#32 (comment)
KyleAMathews/coffee-react-quickstart#10 (comment)
gaearon/react-document-title#1 (comment)
clayallsopp/react.backbone#26
Because there is no warning right away when this happens, they usually discover the problem through invariant violations. Some of them are descriptive (e.g.
Uncaught Error: Invariant Violation: The handler for Route "hello" must be a valid React component
) and I think I even saw warning that said something like "check if two copies of React are loaded", but some are really cryptic:Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs...
.Is there a reason why we don't want to warn right away when two copies of React are loaded?
The text was updated successfully, but these errors were encountered: