Immediate transition fix, avoid stale render (#3901)

This commit is contained in:
Eric Vicenti
2018-04-05 11:35:16 -07:00
parent 4b4709d925
commit 122fd7f08a

View File

@@ -44,11 +44,6 @@ class Transitioner extends React.Component {
this._queuedTransition = null;
}
componentWillMount() {
this._onLayout = this._onLayout.bind(this);
this._onTransitionEnd = this._onTransitionEnd.bind(this);
}
componentDidMount() {
this._isMounted = true;
}
@@ -58,12 +53,15 @@ class Transitioner extends React.Component {
}
componentWillReceiveProps(nextProps) {
const nextScenes = NavigationScenesReducer(
let nextScenes = NavigationScenesReducer(
this.state.scenes,
nextProps.navigation.state,
this.props.navigation.state,
nextProps.descriptors
);
if (!nextProps.navigation.state.isTransitioning) {
nextScenes = filterStale(nextScenes);
}
if (nextScenes === this.state.scenes) {
return;
@@ -151,7 +149,7 @@ class Transitioner extends React.Component {
);
}
_onLayout(event) {
_onLayout = event => {
const { height, width } = event.nativeEvent.layout;
if (
this.state.layout.initWidth === width &&
@@ -176,28 +174,20 @@ class Transitioner extends React.Component {
this._transitionProps = buildTransitionProps(this.props, nextState);
this.setState(nextState);
}
};
_onTransitionEnd() {
_onTransitionEnd = () => {
if (!this._isMounted) {
return;
}
const prevTransitionProps = this._prevTransitionProps;
this._prevTransitionProps = null;
const scenes = this.state.scenes.filter(isSceneNotStale);
const scenes = filterStale(this.state.scenes);
const nextState = {
...this.state,
/**
* Array.prototype.filter creates a new instance of an array
* even if there were no elements removed. There are cases when
* `this.state.scenes` will have no stale scenes (typically when
* pushing a new route). As a result, components that rely on this prop
* might enter an unnecessary render cycle.
*/
scenes:
this.state.scenes.length === scenes.length ? this.state.scenes : scenes,
scenes,
};
this._transitionProps = buildTransitionProps(this.props, nextState);
@@ -225,7 +215,7 @@ class Transitioner extends React.Component {
this._isTransitionRunning = false;
}
});
}
};
}
function buildTransitionProps(props, state) {
@@ -252,6 +242,14 @@ function isSceneNotStale(scene) {
return !scene.isStale;
}
function filterStale(scenes) {
const filtered = scenes.filter(isSceneNotStale);
if (filtered.length === scenes.length) {
return scenes;
}
return filtered;
}
function isSceneActive(scene) {
return scene.isActive;
}