mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-10 09:13:43 +08:00
Add lifecycle polyfill and change away from componentWillMount where possible without too much refactoring
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user