Skip to content

Commit 1787bed

Browse files
fix: requireNativeComponent missing in react-native-web (#3958)
1 parent 1ee969d commit 1787bed

File tree

6 files changed

+48
-4
lines changed

6 files changed

+48
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- Fixes possible missing TTID measurements and spans
1313
- Fix crash when passing array as data to `Sentry.addBreadcrumb({ data: [] })` ([#4021](https://github.com/getsentry/sentry-react-native/pull/4021))
1414
- The expected `data` type is plain JS object, otherwise the data might be lost.
15+
- Fix requireNativeComponent missing in react-native-web #3823 ([#3958](https://github.com/getsentry/sentry-react-native/pull/3958))
1516

1617
### Dependencies
1718

src/js/tracing/timetodisplaynative.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import * as React from 'react';
2-
import type { HostComponent} from 'react-native';
3-
import { requireNativeComponent, UIManager, View } from 'react-native';
2+
import type { HostComponent } from 'react-native';
3+
import { UIManager, View } from 'react-native';
44

5+
import { ReactNativeLibraries } from '../utils/rnlibraries';
56
import type { RNSentryOnDrawReporterProps } from './timetodisplaynative.types';
67

78
const RNSentryOnDrawReporterClass = 'RNSentryOnDrawReporter';
@@ -28,8 +29,8 @@ let RNSentryOnDrawReporter: HostComponent<RNSentryOnDrawReporterProps> | typeof
2829
*/
2930
export const getRNSentryOnDrawReporter = (): typeof RNSentryOnDrawReporter => {
3031
if (!RNSentryOnDrawReporter) {
31-
RNSentryOnDrawReporter = nativeComponentExists
32-
? requireNativeComponent(RNSentryOnDrawReporterClass)
32+
RNSentryOnDrawReporter = nativeComponentExists && ReactNativeLibraries.ReactNative?.requireNativeComponent
33+
? ReactNativeLibraries.ReactNative.requireNativeComponent(RNSentryOnDrawReporterClass)
3334
: RNSentryOnDrawReporterNoop;
3435
}
3536
return RNSentryOnDrawReporter;

src/js/utils/rnlibraries.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,10 @@ export const ReactNativeLibraries: Required<ReactNativeLibrariesInterface> = {
3434
version: Platform.constants?.reactNativeVersion,
3535
},
3636
TurboModuleRegistry,
37+
ReactNative: {
38+
requireNativeComponent: <T>(viewName: string): ReactNative.HostComponent<T> => {
39+
const { requireNativeComponent } = require('react-native');
40+
return requireNativeComponent(viewName);
41+
},
42+
},
3743
};

src/js/utils/rnlibrariesinterface.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ export interface ReactNativeLibrariesInterface {
2525
Promise?: typeof Promise;
2626
ReactNativeVersion?: ReactNative.ReactNativeVersion;
2727
TurboModuleRegistry?: ReactNative.TurboModuleRegistry;
28+
ReactNative?: {
29+
requireNativeComponent?: <T>(viewName: string) => ReactNative.HostComponent<T>;
30+
};
2831
}

src/js/vendor/react-native/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ export type TurboModuleRegistry = {
6565
getEnforcing<T extends TurboModule>(name: string): T;
6666
};
6767

68+
// Adapted from https://github.com/facebook/react-native/blob/3f8340975b35767b192e3118f05d2b039676052e/packages/react-native/types/public/ReactNativeTypes.d.ts#L137
69+
export interface HostComponent<P> extends Pick<React.ComponentClass<P>, Exclude<keyof React.ComponentClass<P>, 'new'>> {
70+
new (props: P, context?: any): React.Component<P> & Readonly<unknown>;
71+
}
72+
6873
// Adapted from https://github.com/facebook/react-native/blob/575ab7862553d7ad7bc753951ed19dcd50d59b95/packages/react-native/Libraries/Utilities/Platform.d.ts#L23-L28
6974
export type ReactNativeVersion = {
7075
version: {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
jest.mock('react-native', () => {
2+
const RN = jest.requireActual('react-native');
3+
RN.UIManager = {};
4+
return RN;
5+
});
6+
7+
jest.mock('../../src/js/utils/rnlibraries', () => {
8+
const webLibrary = jest.requireActual('../../src/js/utils/rnlibraries.web');
9+
return {
10+
...webLibrary,
11+
};
12+
});
13+
14+
import { getRNSentryOnDrawReporter } from '../../src/js/tracing/timetodisplaynative';
15+
import { ReactNativeLibraries } from '../../src/js/utils/rnlibraries';
16+
17+
describe('timetodisplaynative', () => {
18+
test('requireNativeComponent to be undefined', () => {
19+
expect(ReactNativeLibraries).toBeDefined();
20+
expect(ReactNativeLibraries.ReactNative?.requireNativeComponent).not.toBeDefined();
21+
});
22+
23+
test('getRNSentryOnDrawReporter returns Noop', () => {
24+
const drawReported = getRNSentryOnDrawReporter();
25+
26+
expect(drawReported.name).toBe('RNSentryOnDrawReporterNoop');
27+
});
28+
});

0 commit comments

Comments
 (0)