Skip to content

Commit

Permalink
Fix for unsupported platforms (#22)
Browse files Browse the repository at this point in the history
Fixes #13 for real
Fixes react-navigation/react-navigation#5004

Use different `index.js` files for supported and unsupported platforms.

Tested on iOS and on an existing web project that uses react-navigation.

---

!['react-native' does not contain an export named 'requireNativeComponent'.](https://user-images.githubusercontent.com/619186/46323012-8164e300-c5c2-11e8-964e-b6f233776dab.png)

Necolas explained here that this import should not be on any file that runs on web: necolas/react-native-web#507 (comment)
  • Loading branch information
brunolemos authored and kmagiera committed Oct 2, 2018
1 parent 6b2ed8f commit 479616a
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 75 deletions.
1 change: 1 addition & 0 deletions src/screens.android.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './screens.shared';
1 change: 1 addition & 0 deletions src/screens.ios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './screens.shared';
81 changes: 6 additions & 75 deletions src/screens.js
Original file line number Diff line number Diff line change
@@ -1,84 +1,15 @@
import React from 'react';
import {
Animated,
requireNativeComponent,
View,
UIManager,
StyleSheet,
Platform,
} from 'react-native';

let USE_SCREENS = false;
import { Animated, View } from 'react-native';

export function useScreens(shouldUseScreens = true) {
USE_SCREENS = shouldUseScreens;
if (USE_SCREENS && !UIManager['RNSScreen']) {
console.error(
`Screen native module hasn't been linked. Please check the react-native-screens README for more details`
);
if (shouldUseScreens) {
console.warn('react-native-screens is not support on this platform.');
}
}

export function screensEnabled() {
return USE_SCREENS;
return false;
}

const isPlatformSupported = ['android', 'ios'].includes(Platform.OS);

const NativeScreen = isPlatformSupported ? Animated.createAnimatedComponent(
requireNativeComponent('RNSScreen', null)
) : null;

const NativeScreenContainer = isPlatformSupported ? requireNativeComponent(
'RNSScreenContainer',
null
) : null;

export class Screen extends React.Component {
setNativeProps(props) {
this._ref.setNativeProps(props);
}
setRef = ref => {
this._ref = ref;
this.props.onComponentRef && this.props.onComponentRef(ref);
};
render() {
if (!USE_SCREENS) {
// Filter out active prop in this case because it is unused and
// can cause problems depending on react-native version:
// https://github.com/react-navigation/react-navigation/issues/4886

/* eslint-disable no-unused-vars */
const { active, onComponentRef, ...props } = this.props;
export const Screen = Animated.View;

return <Animated.View {...props} ref={this.setRef} />;
} else {
const { style, children, ...rest } = this.props;
return (
<NativeScreen
{...rest}
ref={this.setRef}
style={StyleSheet.absoluteFill}>
{/*
We need to wrap children in additional Animated.View because
of a bug in native driver preventing from both `active` and `styles`
props begin animated in `NativeScreen` component. Once
react-native/pull/20658 is merged we can export native screen directly
and avoid wrapping with `Animated.View`.
*/}
<Animated.View style={style}>{children}</Animated.View>
</NativeScreen>
);
}
}
}

export class ScreenContainer extends React.Component {
render() {
if (!USE_SCREENS) {
return <View {...this.props} />;
} else {
return <NativeScreenContainer {...this.props} />;
}
}
}
export const ScreenContainer = View;
81 changes: 81 additions & 0 deletions src/screens.shared.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react';
import {
Animated,
requireNativeComponent,
View,
UIManager,
StyleSheet,
} from 'react-native';

let USE_SCREENS = false;

export function useScreens(shouldUseScreens = true) {
USE_SCREENS = shouldUseScreens;
if (USE_SCREENS && !UIManager['RNSScreen']) {
console.error(
`Screen native module hasn't been linked. Please check the react-native-screens README for more details`
);
}
}

export function screensEnabled() {
return USE_SCREENS;
}

const NativeScreen = Animated.createAnimatedComponent(
requireNativeComponent('RNSScreen', null)
);

const NativeScreenContainer = requireNativeComponent(
'RNSScreenContainer',
null
);

export class Screen extends React.Component {
setNativeProps(props) {
this._ref.setNativeProps(props);
}
setRef = ref => {
this._ref = ref;
this.props.onComponentRef && this.props.onComponentRef(ref);
};
render() {
if (!USE_SCREENS) {
// Filter out active prop in this case because it is unused and
// can cause problems depending on react-native version:
// https://github.com/react-navigation/react-navigation/issues/4886

/* eslint-disable no-unused-vars */
const { active, onComponentRef, ...props } = this.props;

return <Animated.View {...props} ref={this.setRef} />;
} else {
const { style, children, ...rest } = this.props;
return (
<NativeScreen
{...rest}
ref={this.setRef}
style={StyleSheet.absoluteFill}>
{/*
We need to wrap children in additional Animated.View because
of a bug in native driver preventing from both `active` and `styles`
props begin animated in `NativeScreen` component. Once
react-native/pull/20658 is merged we can export native screen directly
and avoid wrapping with `Animated.View`.
*/}
<Animated.View style={style}>{children}</Animated.View>
</NativeScreen>
);
}
}
}

export class ScreenContainer extends React.Component {
render() {
if (!USE_SCREENS) {
return <View {...this.props} />;
} else {
return <NativeScreenContainer {...this.props} />;
}
}
}

0 comments on commit 479616a

Please sign in to comment.