Fix NavigationTransitioner.

Summary:
- Address the issues reported at 7db7f78dc7 (commitcomment-17575647)
- Fix the logic that reduces the scenes.
- Fix the logic that computes the active scene for `renderOverlay`.

Reviewed By: ericvicenti

Differential Revision: D3344716

fbshipit-source-id: 3fce517ff1de212f412a77936012695bd2dcfc3c
This commit is contained in:
Hedger Wang 2016-05-25 11:26:22 -07:00 committed by Facebook Github Bot 0
parent 80741a170a
commit 8097fcf4e7
3 changed files with 59 additions and 3 deletions

View File

@ -19,6 +19,8 @@ const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
const invariant = require('fbjs/lib/invariant');
import type {
NavigationActionCaller,
NavigationAnimatedValue,
@ -219,13 +221,23 @@ class NavigationTransitioner extends React.Component<any, Props, State> {
scenes,
} = this.state;
const route = navigationState.routes[navigationState.index];
const activeScene = scenes.find(scene => {
return (!scene.isStale && scene.route === route) ?
scene :
undefined;
});
invariant(!!activeScene, 'no active scene found');
return renderOverlay({
layout: this.state.layout,
navigationState,
onNavigate,
position,
progress,
scene: scenes[navigationState.index],
scene: activeScene,
scenes,
});
}

View File

@ -63,7 +63,6 @@ function areScenesShallowEqual(
one.key === two.key &&
one.index === two.index &&
one.isStale === two.isStale &&
one.route === two.route &&
one.route.key === two.route.key
);
}
@ -147,7 +146,20 @@ function NavigationScenesReducer(
staleScenes.forEach(mergeScene);
freshScenes.forEach(mergeScene);
return nextScenes.sort(compareScenes);
nextScenes.sort(compareScenes);
if (nextScenes.length !== scenes.length) {
return nextScenes;
}
if (nextScenes.some(
(scene, index) => !areScenesShallowEqual(scenes[index], scene)
)) {
return nextScenes;
}
// scenes haven't changed.
return scenes;
}
module.exports = NavigationScenesReducer;

View File

@ -97,6 +97,38 @@ describe('NavigationScenesReducer', () => {
]);
});
it('gets same scenes', () => {
const state1 = {
index: 0,
routes: [{key: '1'}, {key: '2'}],
};
const state2 = {
index: 0,
routes: [{key: '1'}, {key: '2'}],
};
const scenes1 = NavigationScenesReducer([], state1, null);
const scenes2 = NavigationScenesReducer(scenes1, state2, state1);
expect(scenes1).toBe(scenes2);
});
it('gets different scenes', () => {
const state1 = {
index: 0,
routes: [{key: '1'}, {key: '2'}],
};
const state2 = {
index: 0,
routes: [{key: '2'}, {key: '1'}],
};
const scenes1 = NavigationScenesReducer([], state1, null);
const scenes2 = NavigationScenesReducer(scenes1, state2, state1);
expect(scenes1).not.toBe(scenes2);
});
it('pops scenes', () => {
// Transition from ['1', '2', '3'] to ['1', '2'].
const scenes = testTransition([