Add lifecycle polyfill and change away from componentWillMount where possible without too much refactoring

This commit is contained in:
Brent Vatne
2018-03-08 21:30:06 -08:00
parent d9f2f3c2bb
commit 7b9c0cb57e
5 changed files with 57 additions and 60 deletions

View File

@@ -1,10 +1,37 @@
import React from 'react';
import { Linking } from 'react-native';
import withLifecyclePolyfill from 'react-lifecycles-compat';
import { BackHandler } from './PlatformHelpers';
import NavigationActions from './NavigationActions';
import addNavigationHelpers from './addNavigationHelpers';
import invariant from './utils/invariant';
function isStateful(props) {
return !props.navigation;
}
function validateProps(props) {
if (isStateful(props)) {
return;
}
const { navigation, screenProps, ...containerProps } = props;
const keys = Object.keys(containerProps);
if (keys.length !== 0) {
throw new Error(
'This navigator has both navigation and container props, so it is ' +
`unclear if it should own its own state. Remove props: "${keys.join(
', '
)}" ` +
'if the navigator should get its state from the navigation prop. If the ' +
'navigator should maintain its own state, do not pass a navigation prop.'
);
}
}
/**
* Create an HOC that injects the navigation and manages the navigation state
* in case it's not passed from above.
@@ -18,12 +45,17 @@ export default function createNavigationContainer(Component) {
static router = Component.router;
static navigationOptions = null;
static getDerivedStateFromProps(nextProps, prevState) {
validateProps(nextProps);
return null;
}
_actionEventSubscribers = new Set();
constructor(props) {
super(props);
this._validateProps(props);
validateProps(props);
this._initialAction = NavigationActions.init();
@@ -48,28 +80,7 @@ export default function createNavigationContainer(Component) {
}
_isStateful() {
return !this.props.navigation;
}
_validateProps(props) {
if (this._isStateful()) {
return;
}
const { navigation, screenProps, ...containerProps } = props;
const keys = Object.keys(containerProps);
if (keys.length !== 0) {
throw new Error(
'This navigator has both navigation and container props, so it is ' +
`unclear if it should own its own state. Remove props: "${keys.join(
', '
)}" ` +
'if the navigator should get its state from the navigation prop. If the ' +
'navigator should maintain its own state, do not pass a navigation prop.'
);
}
return isStateful(this.props);
}
_urlToPathAndParams(url) {
@@ -127,10 +138,6 @@ export default function createNavigationContainer(Component) {
}
}
componentWillReceiveProps(nextProps) {
this._validateProps(nextProps);
}
componentDidUpdate() {
// Clear cached _nav every tick
if (this._nav === this.state.nav) {
@@ -227,5 +234,5 @@ export default function createNavigationContainer(Component) {
}
}
return NavigationContainer;
return withLifecyclePolyfill(NavigationContainer);
}

View File

@@ -17,7 +17,7 @@ export default class DrawerView extends React.PureComponent {
: this.props.navigationConfig.drawerWidth,
};
componentWillMount() {
componentDidMount() {
Dimensions.addEventListener('change', this._updateWidth);
}
@@ -25,9 +25,10 @@ export default class DrawerView extends React.PureComponent {
Dimensions.removeEventListener('change', this._updateWidth);
}
componentWillReceiveProps(nextProps) {
const { isDrawerOpen } = nextProps.navigation.state;
const wasDrawerOpen = this.props.navigation.state.isDrawerOpen;
componentDidUpdate(prevProps, prevState) {
const { isDrawerOpen } = this.props.navigation.state;
const wasDrawerOpen = prevProps.navigation.state.isDrawerOpen;
if (isDrawerOpen && !wasDrawerOpen) {
this._drawer.openDrawer();
} else if (wasDrawerOpen && !isDrawerOpen) {

View File

@@ -8,6 +8,14 @@ import SceneView from './SceneView';
const FAR_FAR_AWAY = 3000; // this should be big enough to move the whole view out of its container
class ResourceSavingSceneView extends React.PureComponent {
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.isFocused && !prevState.awake) {
return { awake: true };
} else {
return null;
}
}
constructor(props) {
super();
@@ -16,14 +24,6 @@ class ResourceSavingSceneView extends React.PureComponent {
};
}
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.isFocused && !prevState.awake) {
return { awake: true };
}
return null;
}
render() {
const { awake } = this.state;
const {

View File

@@ -352,7 +352,7 @@ class StackViewLayout extends React.Component {
return (
<View {...handlers} style={containerStyle}>
<View style={styles.scenes}>
{scenes.map((s: *) => this._renderCard(s))}
{scenes.map(s => this._renderCard(s))}
</View>
{floatingHeader}
</View>

View File

@@ -16,25 +16,14 @@ export default function createPointerEventsContainer(Component) {
this._pointerEvents = this._computePointerEvents();
}
componentWillMount() {
this._onPositionChange = this._onPositionChange.bind(this);
this._onComponentRef = this._onComponentRef.bind(this);
}
componentDidMount() {
this._bindPosition(this.props);
}
componentWillUnmount() {
this._positionListener && this._positionListener.remove();
}
componentWillReceiveProps(nextProps) {
this._bindPosition(nextProps);
}
render() {
this._bindPosition();
this._pointerEvents = this._computePointerEvents();
return (
<Component
{...this.props}
@@ -44,7 +33,7 @@ export default function createPointerEventsContainer(Component) {
);
}
_onComponentRef(component) {
_onComponentRef = component => {
this._component = component;
if (component) {
invariant(
@@ -52,17 +41,17 @@ export default function createPointerEventsContainer(Component) {
'component must implement method `setNativeProps`'
);
}
}
};
_bindPosition(props) {
_bindPosition() {
this._positionListener && this._positionListener.remove();
this._positionListener = new AnimatedValueSubscription(
props.position,
this.props.position,
this._onPositionChange
);
}
_onPositionChange() {
_onPositionChange = () => {
if (this._component) {
const pointerEvents = this._computePointerEvents();
if (this._pointerEvents !== pointerEvents) {
@@ -70,7 +59,7 @@ export default function createPointerEventsContainer(Component) {
this._component.setNativeProps({ pointerEvents });
}
}
}
};
_computePointerEvents() {
const { navigation, position, scene } = this.props;