30
30
var AnimationsDebugModule = require ( 'NativeModules' ) . AnimationsDebugModule ;
31
31
var Dimensions = require ( 'Dimensions' ) ;
32
32
var InteractionMixin = require ( 'InteractionMixin' ) ;
33
+ var Map = require ( 'Map' ) ;
33
34
var NavigationContext = require ( 'NavigationContext' ) ;
34
35
var NavigatorBreadcrumbNavigationBar = require ( 'NavigatorBreadcrumbNavigationBar' ) ;
35
36
var NavigatorNavigationBar = require ( 'NavigatorNavigationBar' ) ;
@@ -257,6 +258,8 @@ var Navigator = React.createClass({
257
258
} ,
258
259
259
260
getInitialState : function ( ) {
261
+ this . _renderedSceneMap = new Map ( ) ;
262
+
260
263
var routeStack = this . props . initialRouteStack || [ this . props . initialRoute ] ;
261
264
invariant (
262
265
routeStack . length >= 1 ,
@@ -276,10 +279,6 @@ var Navigator = React.createClass({
276
279
) ,
277
280
idStack : routeStack . map ( ( ) => getuid ( ) ) ,
278
281
routeStack,
279
- // `updatingRange*` allows us to only render the visible or staged scenes
280
- // On first render, we will render every scene in the initialRouteStack
281
- updatingRangeStart : 0 ,
282
- updatingRangeLength : routeStack . length ,
283
282
presentedIndex : initialRouteIndex ,
284
283
transitionFromIndex : null ,
285
284
activeGesture : null ,
@@ -351,8 +350,6 @@ var Navigator = React.createClass({
351
350
sceneConfigStack : nextRouteStack . map (
352
351
this . props . configureScene
353
352
) ,
354
- updatingRangeStart : 0 ,
355
- updatingRangeLength : nextRouteStack . length ,
356
353
presentedIndex : destIndex ,
357
354
activeGesture : null ,
358
355
transitionFromIndex : null ,
@@ -829,11 +826,6 @@ var Navigator = React.createClass({
829
826
return false ;
830
827
} ,
831
828
832
- _resetUpdatingRange : function ( ) {
833
- this . state . updatingRangeStart = 0 ;
834
- this . state . updatingRangeLength = this . state . routeStack . length ;
835
- } ,
836
-
837
829
_getDestIndexWithinBounds : function ( n ) {
838
830
var currentIndex = this . state . presentedIndex ;
839
831
var destIndex = currentIndex + n ;
@@ -851,15 +843,8 @@ var Navigator = React.createClass({
851
843
852
844
_jumpN : function ( n ) {
853
845
var destIndex = this . _getDestIndexWithinBounds ( n ) ;
854
- var requestTransitionAndResetUpdatingRange = ( ) => {
855
- this . _enableScene ( destIndex ) ;
856
- this . _transitionTo ( destIndex ) ;
857
- this . _resetUpdatingRange ( ) ;
858
- } ;
859
- this . setState ( {
860
- updatingRangeStart : destIndex ,
861
- updatingRangeLength : 1 ,
862
- } , requestTransitionAndResetUpdatingRange ) ;
846
+ this . _enableScene ( destIndex ) ;
847
+ this . _transitionTo ( destIndex ) ;
863
848
} ,
864
849
865
850
jumpTo : function ( route ) {
@@ -891,18 +876,14 @@ var Navigator = React.createClass({
891
876
var nextAnimationConfigStack = activeAnimationConfigStack . concat ( [
892
877
this . props . configureScene ( route ) ,
893
878
] ) ;
894
- var requestTransitionAndResetUpdatingRange = ( ) => {
895
- this . _enableScene ( destIndex ) ;
896
- this . _transitionTo ( destIndex ) ;
897
- this . _resetUpdatingRange ( ) ;
898
- } ;
899
879
this . setState ( {
900
880
idStack : nextIDStack ,
901
881
routeStack : nextStack ,
902
882
sceneConfigStack : nextAnimationConfigStack ,
903
- updatingRangeStart : nextStack . length - 1 ,
904
- updatingRangeLength : 1 ,
905
- } , requestTransitionAndResetUpdatingRange ) ;
883
+ } , ( ) => {
884
+ this . _enableScene ( destIndex ) ;
885
+ this . _transitionTo ( destIndex ) ;
886
+ } ) ;
906
887
} ,
907
888
908
889
_popN : function ( n ) {
@@ -958,10 +939,7 @@ var Navigator = React.createClass({
958
939
idStack : nextIDStack ,
959
940
routeStack : nextRouteStack ,
960
941
sceneConfigStack : nextAnimationModeStack ,
961
- updatingRangeStart : index ,
962
- updatingRangeLength : 1 ,
963
942
} , ( ) => {
964
- this . _resetUpdatingRange ( ) ;
965
943
if ( index === this . state . presentedIndex ) {
966
944
this . _emitWillFocus ( route ) ;
967
945
this . _emitDidFocus ( route ) ;
@@ -1034,67 +1012,15 @@ var Navigator = React.createClass({
1034
1012
var newStackLength = index + 1 ;
1035
1013
// Remove any unneeded rendered routes.
1036
1014
if ( newStackLength < this . state . routeStack . length ) {
1037
- var updatingRangeStart = newStackLength ; // One past the top
1038
- var updatingRangeLength = this . state . routeStack . length - newStackLength + 1 ;
1039
1015
this . state . idStack . slice ( newStackLength ) . map ( ( removingId ) => {
1040
1016
this . _itemRefs [ removingId ] = null ;
1041
1017
} ) ;
1042
1018
this . setState ( {
1043
- updatingRangeStart : updatingRangeStart ,
1044
- updatingRangeLength : updatingRangeLength ,
1045
1019
sceneConfigStack : this . state . sceneConfigStack . slice ( 0 , newStackLength ) ,
1046
1020
idStack : this . state . idStack . slice ( 0 , newStackLength ) ,
1047
1021
routeStack : this . state . routeStack . slice ( 0 , newStackLength ) ,
1048
- } , this . _resetUpdatingRange ) ;
1049
- }
1050
- } ,
1051
-
1052
- _renderOptimizedScenes : function ( ) {
1053
- // To avoid rendering scenes that are not visible, we use
1054
- // updatingRangeStart and updatingRangeLength to track the scenes that need
1055
- // to be updated.
1056
-
1057
- // To avoid visual glitches, we never re-render scenes during a transition.
1058
- // We assume that `state.updatingRangeLength` will have a length during the
1059
- // initial render of any scene
1060
- var shouldRenderScenes = this . state . updatingRangeLength !== 0 ;
1061
- if ( shouldRenderScenes ) {
1062
- return (
1063
- < StaticContainer shouldUpdate = { true } >
1064
- < View
1065
- style = { styles . transitioner }
1066
- { ...this . panGesture . panHandlers }
1067
- onTouchStart = { this . _handleTouchStart }
1068
- onResponderTerminationRequest = {
1069
- this . _handleResponderTerminationRequest
1070
- } >
1071
- { this . state . routeStack . map ( this . _renderOptimizedScene ) }
1072
- </ View >
1073
- </ StaticContainer >
1074
- ) ;
1022
+ } ) ;
1075
1023
}
1076
- // If no scenes are changing, we can save render time. React will notice
1077
- // that we are rendering a StaticContainer in the same place, so the
1078
- // existing element will be updated. When React asks the element
1079
- // shouldComponentUpdate, the StaticContainer will return false, and the
1080
- // children from the previous reconciliation will remain.
1081
- return (
1082
- < StaticContainer shouldUpdate = { false } />
1083
- ) ;
1084
- } ,
1085
-
1086
- _renderOptimizedScene : function ( route , i ) {
1087
- var shouldRenderScene =
1088
- i >= this . state . updatingRangeStart &&
1089
- i <= this . state . updatingRangeStart + this . state . updatingRangeLength ;
1090
- var scene = shouldRenderScene ? this . _renderScene ( route , i ) : null ;
1091
- return (
1092
- < StaticContainer
1093
- key = { 'nav' + i }
1094
- shouldUpdate = { shouldRenderScene } >
1095
- { scene }
1096
- </ StaticContainer >
1097
- ) ;
1098
1024
} ,
1099
1025
1100
1026
_renderScene : function ( route , i ) {
@@ -1146,9 +1072,30 @@ var Navigator = React.createClass({
1146
1072
} ,
1147
1073
1148
1074
render : function ( ) {
1075
+ var newRenderedSceneMap = new Map ( ) ;
1076
+ var scenes = this . state . routeStack . map ( ( route , index ) => {
1077
+ var renderedScene ;
1078
+ if ( this . _renderedSceneMap . has ( route ) &&
1079
+ index !== this . state . presentedIndex ) {
1080
+ renderedScene = this . _renderedSceneMap . get ( route ) ;
1081
+ } else {
1082
+ renderedScene = this . _renderScene ( route , index ) ;
1083
+ }
1084
+ newRenderedSceneMap . set ( route , renderedScene ) ;
1085
+ return renderedScene ;
1086
+ } ) ;
1087
+ this . _renderedSceneMap = newRenderedSceneMap ;
1149
1088
return (
1150
1089
< View style = { [ styles . container , this . props . style ] } >
1151
- { this . _renderOptimizedScenes ( ) }
1090
+ < View
1091
+ style = { styles . transitioner }
1092
+ { ...this . panGesture . panHandlers }
1093
+ onTouchStart = { this . _handleTouchStart }
1094
+ onResponderTerminationRequest = {
1095
+ this . _handleResponderTerminationRequest
1096
+ } >
1097
+ { scenes }
1098
+ </ View >
1152
1099
{ this . _renderNavigationBar ( ) }
1153
1100
</ View >
1154
1101
) ;
0 commit comments