-
-
Notifications
You must be signed in to change notification settings - Fork 987
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
fix: web compatibility #406
fix: web compatibility #406
Conversation
@jaulz |
@osdnk sorry, I found some issues with the original commit and pushed a fix now 😊As requested I added some comments and it should be in a state where you could please take a look. I tried to touch the existing files at a minimum and also cross checked on native devices if it still works as expected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't digged in this PR yet. Now leaving one comment, but it's not crucial.
GestureHandler.web.js
Outdated
import gestureHandlerRootHOC from './gestureHandlerRootHOC'; | ||
|
||
const State = { | ||
UNDETERMINED: 'UNDETERMINED', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move it out somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should we move out in detail? State constants?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. If you need them here, I wish to have them in separated file in order not to duplicate code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, makes more than sense 😊 Was not sure before since these constants were used in GestureHandler.js
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, well, we intentionally wanted to take them from native site every time. How I think there's no need to do it. You could think about removing extracting from from Java and Objective-C if it's not big deal for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, the constants are used in the native part as well. Hence it actually makes sense to read them in the JavaScript part from the native side. Should I undo the changes in GestureHandler.js
for the time being?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's fine now
AnimatedEvent.web.js
Outdated
@@ -0,0 +1,3 @@ | |||
import AnimatedEvent from 'react-native-web/dist/vendor/react-native/Animated/AnimatedEvent'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If AnimatedEvent
needs to be used directly, you may want to ask that it is added to the Animated
export from React Native rather than relying on the fragility of reaching into internals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will check on their repository and raise a PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will keep track here: facebook/react-native#22984
GestureHandler.web.js
Outdated
ToolbarAndroid, | ||
ViewPagerAndroid, | ||
DrawerLayoutAndroid, | ||
WebView, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This module is being removed from React Native and isn't included in react-native-web
either
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which one in detail? Currently, I see that all of these components are exported though some of them as UnimplementedView
which is fine I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the info!
GestureHandler.web.js
Outdated
} | ||
|
||
setNativeProps() { | ||
// No implementation so far but is needed to avoid null calls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to use this.container.current.setNativeProps
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I intentionally left this out since I think we do not need to pass on props for stub components. This would just generate warnings since most of the props are custom.
GestureHandler.web.js
Outdated
x, | ||
}, | ||
}); | ||
node.addEventListener('click', clickHandler); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using these DOM events directly means you're not hooked into the responder event system
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have any link for me to see how we could improve this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with the behaviour/implementation of the native TapGestureHandler
. But if it turns out to be preferable to use the responder events, you could pass the event handlers to createHandler
and forward them to the component.
GestureHandler.web.js
Outdated
static displayName = name; | ||
|
||
render() { | ||
return <TouchableWithoutFeedback {...this.props} />; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If these are meant to be used as buttons in the UI, you should add accessibilityRole="button"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the hint!
Sorry for the interjection: I was trying this PR, but the thing I run into is that my babel transforms the access to
(i.e., it replaces this with undefined). Clearly something is wrong with the way I have setup my babel for the |
That just looks like incorrect code. |
@necolas Funny. If I change those lines to
It compiles with webpack, but then
The exact opposite behaviour. |
I am fairly certain this is related to the Hot Module Reloading transform inserted by metro here by merging into Transforming the file in question with But the actual code generated by The problem goes away if I manually edit the file linked above ( I can see that @osdnk added this code quite recently. Maybe as a workaround for this issue we could rewrite that part and pull the re-used proptypes into the global module scope. |
I will merge it if needed. |
fix: web compatibility
Fixes the issue we encountered #406 (comment) To review, the problem is as follows: The correct syntax is: ``` static propTypes = { ...GenericTouchable.internalPropTypes } ``` Metro/Babel compiles this to: ``` // Define GenericTouchable GenericTouchable.propTypes = (0, _objectSpread2.default)({}, GenericTouchable.internalPropTypes, GenericTouchable.publicPropTypes); ``` But when metro then runs the HMR transform, this becomes: ``` // Create _class _class.propTypes = (0, _objectSpread2.default)({}, GenericTouchable.internalPropTypes, GenericTouchable.publicPropTypes), ``` It rewrites the class name to `_class` during initialization, but misses the references in the spread, which then causes a undefined-access exception. See this Gist for full outputs: https://gist.github.com/miracle2k/3bc7f1c50080397dbf0d92cfb3101677#file-generictouchable-babel-with-metro-preset-js Part of the problem seems to be that metro uses a very old version of [react-hot-loader](facebook/metro#336). The code as it is currently in the library, using `...this.publicPropTypes` has two problems: First, it does not compile at all with babel, when this library becomes imported as part of using `react-native-web`. Second, while it does compile using metro, the generated code instead will be: ``` // Create _class _class.propTypes = (0, _objectSpread2.default)({}, this.internalPropTypes, this.publicPropTypes), ``` With `this` probably referring to the window or global scope, thus not causing a crash, but not actually setting the proptypes correctly.
@osdnk @brentvatne it would be great if could you have another look. I assume we could even implement a proper |
May I ask what's the status here? |
@kmagiera could you please check the latest version? |
excited for this. thanks for all the work here folks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jaulz so much for working on this. This PR is excellent 👌
I left one small comment, however I'm going to merge this anyways. If you would like to make respond to that comment please submit a separate PR.
}; | ||
|
||
render() { | ||
let Handler = handlers[handlerName]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think this check could be moved outside of the render method and directly to createHandler
@kmagiera do you have any timeline for a new release? Thanks for merging by the way 😊 |
will try to send out new release tomorrow |
just tried using release with this PR for web and ran into errors. what do we need to configure to get it running - looks like it'd be great we we could just have a simple alias (like we do react-native to react-native-web) |
@alidcastano if you add the |
Summary: Initially if a `react-native-web` project were to use a library that required internals `expo/webpack-config` would polyfill those internals. This `Platform.web` was used for cases where `react-native` modules needed other internal `react-native` modules, ex: `Animated/src/AnimatedEvent -> Renderer/shims/ReactNative -> Renderer/oss/ReactNativeRenderer-dev -> Core/InitializeCore -> Devtools/setupDevtools -> WebSocket/WebSocket -> Utilities/Platform` The consensus is that if any `react-native` library references a `react-native` internal (ex: `react-native/*`), it should continue to throw errors. We've removed the use of internals from all of the Unimodules, `react-navigation`, and `react-native-gesture-handler`. This covers a wide enough area for a lot of projects to get web support. * Add emitters for libs referencing internals necolas/react-native-web#1275 * Remove monkey patch that bundles RN, libs that use internals will crash instead expo/expo-cli#409 * Remove all unsupported internals and polyfills from the Expo suite expo/expo#3676 * Remove internals from react-native-gesture-handler software-mansion/react-native-gesture-handler#406 * Related #23387 [GENERAL] [REMOVED] - Platform.web.js Pull Request resolved: #23830 Differential Revision: D14406145 Pulled By: hramos fbshipit-source-id: bdda99a334d33f5543fdb954eb80e2e7186f985a
RNGestureHandlerModule.updateGestureHandler(this._handlerTag, newConfig); | ||
}; | ||
|
||
_dropGestureHandler = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it not used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_dropGestureHandler
is not used anywhere. Isn't it a bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, good catch! Sorry..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
np, thanks!
/pull/406/files#diff-88fa64c878efe14d137f130ddbe000a5R185 From unknown reason, it has been changed here. Probably it's just a mistake, but it was leading to memory leaks.
I opened an issue for two encountered bugs here: #632 |
…-mansion#412) Fixes the issue we encountered software-mansion#406 (comment) To review, the problem is as follows: The correct syntax is: ``` static propTypes = { ...GenericTouchable.internalPropTypes } ``` Metro/Babel compiles this to: ``` // Define GenericTouchable GenericTouchable.propTypes = (0, _objectSpread2.default)({}, GenericTouchable.internalPropTypes, GenericTouchable.publicPropTypes); ``` But when metro then runs the HMR transform, this becomes: ``` // Create _class _class.propTypes = (0, _objectSpread2.default)({}, GenericTouchable.internalPropTypes, GenericTouchable.publicPropTypes), ``` It rewrites the class name to `_class` during initialization, but misses the references in the spread, which then causes a undefined-access exception. See this Gist for full outputs: https://gist.github.com/miracle2k/3bc7f1c50080397dbf0d92cfb3101677#file-generictouchable-babel-with-metro-preset-js Part of the problem seems to be that metro uses a very old version of [react-hot-loader](facebook/metro#336). The code as it is currently in the library, using `...this.publicPropTypes` has two problems: First, it does not compile at all with babel, when this library becomes imported as part of using `react-native-web`. Second, while it does compile using metro, the generated code instead will be: ``` // Create _class _class.propTypes = (0, _objectSpread2.default)({}, this.internalPropTypes, this.publicPropTypes), ``` With `this` probably referring to the window or global scope, thus not causing a crash, but not actually setting the proptypes correctly.
The motivation for me was to use `react-navigation@^3` and I stumbled across quite a few missing imports. This PR will introduce some shims so it shouldn't be a problem anymore.
software-mansion/pull/406/files#diff-88fa64c878efe14d137f130ddbe000a5R185 From unknown reason, it has been changed here. Probably it's just a mistake, but it was leading to memory leaks.
When trying to import from RNGH in react native web project, it throws with this error, Minimum reproducible demo, |
@Manishalexin - you should use babel-preset-expo and the react-native-web setup that you get when you init a project with here's an example of it running in snack: https://snack.expo.io/@notbrent/jealous-coffee |
Thank you @brentvatne it's working with babel-preset-expo in babel config and I have to use I am using a bare workflow, with react native cli. |
Also running into this on a
|
I do not use expo, how can we solve the dreaded Thanks a lot! I also tried the
EDIT: This was related to |
Hi, I am trying to add react-native-web support on an existing react native ios android application, I still have error such as this one :
Looking at your discussion, I assume it should work out of the box with react-native-gesture-handler v1.6.0, why am I still getting those requireNative? Thanks a lot for this awsome lib! |
The motivation for me was to use
react-navigation@^3
and I stumbled across quite a few missing imports. This PR will introduce some shims so it shouldn't be a problem anymore.