Skip to content

Commit ee464b5

Browse files
miracle2kosdnk
authored andcommitted
Workaround metro not compiling static properties correctly. (#412)
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.
1 parent 786530a commit ee464b5

File tree

1 file changed

+40
-31
lines changed

1 file changed

+40
-31
lines changed

touchables/GenericTouchable.js

+40-31
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,54 @@ export const TOUCHABLE_STATE = {
1616
MOVED_OUTSIDE: 2,
1717
};
1818

19+
20+
const PublicPropTypes = {
21+
// Decided to drop not used fields from RN's implementation.
22+
// e.g. onBlur and onFocus as well as deprecated props.
23+
accessible: PropTypes.bool,
24+
accessibilityLabel: PropTypes.node,
25+
accessibilityHint: PropTypes.string,
26+
hitSlop: PropTypes.shape({
27+
top: PropTypes.number,
28+
left: PropTypes.number,
29+
bottom: PropTypes.number,
30+
right: PropTypes.number,
31+
}),
32+
disabled: PropTypes.bool,
33+
onPress: PropTypes.func,
34+
onPressIn: PropTypes.func,
35+
onPressOut: PropTypes.func,
36+
onLayout: PropTypes.func,
37+
onLongPress: PropTypes.func,
38+
nativeID: PropTypes.string,
39+
testID: PropTypes.string,
40+
delayPressIn: PropTypes.number,
41+
delayPressOut: PropTypes.number,
42+
delayLongPress: PropTypes.number,
43+
};
44+
45+
46+
const InternalPropTypes = {
47+
extraButtonProps: PropTypes.object,
48+
onStateChange: PropTypes.func,
49+
};
50+
51+
1952
/**
2053
* GenericTouchable is not intented to be used as it.
2154
* Should be treated as a source for the rest of touchables
2255
*/
2356

2457
export default class GenericTouchable extends Component {
25-
static publicPropTypes = {
26-
// Decided to drop not used fields from RN's implementation.
27-
// e.g. onBlur and onFocus as well as deprecated props.
28-
accessible: PropTypes.bool,
29-
accessibilityLabel: PropTypes.node,
30-
accessibilityHint: PropTypes.string,
31-
hitSlop: PropTypes.shape({
32-
top: PropTypes.number,
33-
left: PropTypes.number,
34-
bottom: PropTypes.number,
35-
right: PropTypes.number,
36-
}),
37-
disabled: PropTypes.bool,
38-
onPress: PropTypes.func,
39-
onPressIn: PropTypes.func,
40-
onPressOut: PropTypes.func,
41-
onLayout: PropTypes.func,
42-
onLongPress: PropTypes.func,
43-
nativeID: PropTypes.string,
44-
testID: PropTypes.string,
45-
delayPressIn: PropTypes.number,
46-
delayPressOut: PropTypes.number,
47-
delayLongPress: PropTypes.number,
48-
};
49-
50-
static internalPropTypes = {
51-
extraButtonProps: PropTypes.object,
52-
onStateChange: PropTypes.func,
53-
};
58+
static publicPropTypes = PublicPropTypes;
59+
static internalPropTypes = InternalPropTypes;
5460

61+
// The prop type collections have to be outside of the class, as metro
62+
// at this time does not compile `this.foo` correctly if HMR is enabled.
63+
// https://github.com/kmagiera/react-native-gesture-handler/pull/406#issuecomment-453779977
5564
static propTypes = {
56-
...this.internalPropTypes,
57-
...this.publicPropTypes,
65+
...InternalPropTypes,
66+
...PublicPropTypes,
5867
};
5968

6069
static defaultProps = {

0 commit comments

Comments
 (0)