11const React = require ( 'react' ) ;
22const {
33 PropTypes,
4+ Component,
45} = React ;
56const ReactNative = require ( 'react-native' ) ;
67const {
@@ -15,9 +16,11 @@ const {
1516} = ReactNative ;
1617const TimerMixin = require ( 'react-timer-mixin' ) ;
1718
19+ const SceneComponent = require ( './SceneComponent' ) ;
1820const DefaultTabBar = require ( './DefaultTabBar' ) ;
1921const ScrollableTabBar = require ( './ScrollableTabBar' ) ;
2022
23+
2124const ScrollableTabView = React . createClass ( {
2225 mixins : [ TimerMixin , ] ,
2326 statics : {
@@ -56,6 +59,7 @@ const ScrollableTabView = React.createClass({
5659 currentPage : this . props . initialPage ,
5760 scrollValue : new Animated . Value ( this . props . initialPage ) ,
5861 containerWidth : Dimensions . get ( 'window' ) . width ,
62+ sceneKeys : this . updateSceneKeys ( this . props . children , [ ] , this . props . initialPage ) ,
5963 } ;
6064 } ,
6165
@@ -83,7 +87,12 @@ const ScrollableTabView = React.createClass({
8387 }
8488 }
8589
86- this . setState ( { currentPage : pageNumber , } ) ;
90+ if ( this . props . children . length !== this . state . sceneKeys . length ) {
91+ let newKeys = this . updateSceneKeys ( this . props . children , this . state . sceneKeys , pageNumber ) ;
92+ this . setState ( { currentPage : pageNumber , sceneKeys : newKeys , } ) ;
93+ } else {
94+ this . setState ( { currentPage : pageNumber , } ) ;
95+ }
8796 } ,
8897
8998 renderTabBar ( props ) {
@@ -96,8 +105,26 @@ const ScrollableTabView = React.createClass({
96105 }
97106 } ,
98107
108+ updateSceneKeys ( children , sceneKeys = [ ] , currentPage ) {
109+ let newKeys = [ ] ;
110+ children . forEach ( ( child , idx ) => {
111+ let key = this . _makeSceneKey ( child , idx ) ;
112+ if ( this . _keyExists ( sceneKeys , key ) || currentPage === idx ) newKeys . push ( key ) ;
113+ } ) ;
114+ return newKeys ;
115+ } ,
116+
117+ _keyExists ( sceneKeys , key ) {
118+ return sceneKeys . find ( ( sceneKey ) => key === sceneKey ) ;
119+ } ,
120+
121+ _makeSceneKey ( child , idx ) {
122+ return child . props . tabLabel + '_' + idx ;
123+ } ,
124+
99125 renderScrollableContent ( ) {
100126 if ( Platform . OS === 'ios' ) {
127+ const scenes = this . _composeScenes ( ) ;
101128 return (
102129 < ScrollView
103130 horizontal
@@ -133,16 +160,11 @@ const ScrollableTabView = React.createClass({
133160 alwaysBounceVertical = { false }
134161 keyboardDismissMode = "on-drag"
135162 { ...this . props . contentProps } >
136- { this . _children ( ) . map ( ( child , idx ) => {
137- return < View
138- key = { child . key }
139- style = { { width : this . state . containerWidth , } } >
140- { child }
141- </ View > ;
142- } ) }
163+ { scenes }
143164 </ ScrollView >
144165 ) ;
145166 } else {
167+ const scenes = this . _composeScenes ( ) ;
146168 return (
147169 < ViewPagerAndroid
148170 key = { this . _children ( ) . length }
@@ -157,26 +179,43 @@ const ScrollableTabView = React.createClass({
157179 } }
158180 ref = { ( scrollView ) => { this . scrollView = scrollView ; } }
159181 { ...this . props . contentProps } >
160- { this . _children ( ) . map ( ( child , idx ) => {
161- return < View
162- key = { child . key }
163- style = { { width : this . state . containerWidth , } } >
164- { child }
165- </ View > ;
166- } ) }
182+ { scenes }
167183 </ ViewPagerAndroid >
168184 ) ;
169185 }
170186 } ,
171187
188+ _composeScenes ( ) {
189+ return this . _children ( ) . map ( ( child , idx ) => {
190+ let key = this . _makeSceneKey ( child , idx ) ;
191+ return (
192+ < SceneComponent
193+ key = { child . key }
194+ selected = { ( this . state . currentPage === idx ) }
195+ style = { { width : this . state . containerWidth , } }
196+ >
197+ { this . _keyExists ( this . state . sceneKeys , key ) ? child : < View tabLabel = { child . props . tabLabel } /> }
198+ </ SceneComponent >
199+ ) ;
200+ } ) ;
201+ } ,
202+
172203 _updateSelectedPage ( currentPage ) {
173204 let localCurrentPage = currentPage ;
174205 if ( typeof localCurrentPage === 'object' ) {
175206 localCurrentPage = currentPage . nativeEvent . position ;
176207 }
177- this . setState ( { currentPage : localCurrentPage , } , ( ) => {
178- this . props . onChangeTab ( { i : localCurrentPage , ref : this . _children ( ) [ localCurrentPage ] , } ) ;
179- } ) ;
208+ // scenekeys length and children length is same then no need to update the keys as all are stored by now
209+ if ( this . props . children . length !== this . state . sceneKeys . length ) {
210+ let newKeys = this . updateSceneKeys ( this . props . children , this . state . sceneKeys , localCurrentPage ) ;
211+ this . setState ( { currentPage : localCurrentPage , sceneKeys : newKeys , } , ( ) => {
212+ this . props . onChangeTab ( { i : localCurrentPage , ref : this . _children ( ) [ localCurrentPage ] , } ) ;
213+ } ) ;
214+ } else {
215+ this . setState ( { currentPage : localCurrentPage , } , ( ) => {
216+ this . props . onChangeTab ( { i : localCurrentPage , ref : this . _children ( ) [ localCurrentPage ] , } ) ;
217+ } ) ;
218+ }
180219 } ,
181220
182221 _updateScrollValue ( value ) {
0 commit comments