@@ -6,6 +6,12 @@ import Row from './Row';
6
6
const AUTOSCROLL_AREA_HEIGTH = 60 ;
7
7
const AUTOSCROLL_INTERVAL = 100 ;
8
8
9
+ function uniqueRowKey ( key ) {
10
+ return `${ key } ${ uniqueRowKey . id } `
11
+ }
12
+
13
+ uniqueRowKey . id = 0
14
+
9
15
export default class SortableList extends Component {
10
16
static propTypes = {
11
17
data : PropTypes . object . isRequired ,
@@ -42,6 +48,7 @@ export default class SortableList extends Component {
42
48
state = {
43
49
order : this . props . order || Object . keys ( this . props . data ) ,
44
50
rowsLayouts : null ,
51
+ containerLayout : null ,
45
52
data : this . props . data ,
46
53
activeRowKey : null ,
47
54
activeRowIndex : null ,
@@ -54,37 +61,37 @@ export default class SortableList extends Component {
54
61
} ;
55
62
56
63
componentDidMount ( ) {
57
- Promise . all ( [ ...this . _rowsLayouts ] )
58
- . then ( ( rowsLayouts ) => {
59
- // Can get correct container’s layout only after rows’s layouts.
60
- this . _container . measure ( ( x , y , width , height , pageX , pageY ) => {
61
- const rowsLayoutsByKey = { } ;
62
- let contentHeight = 0 ;
63
-
64
- rowsLayouts . forEach ( ( { rowKey, layout} ) => {
65
- rowsLayoutsByKey [ rowKey ] = layout ;
66
- contentHeight += layout . height ;
67
- } ) ;
64
+ this . _onLayotRows ( ) ;
65
+ }
68
66
69
- this . setState ( {
70
- containerLayout : { x, y, width, height, pageX, pageY} ,
71
- rowsLayouts : rowsLayoutsByKey ,
72
- contentHeight,
73
- } , ( ) => {
74
- Animated . spring ( this . state . style . opacity , {
75
- toValue : 1 ,
76
- } ) . start ( ( ) => ( this . _areRowsAnimated = true ) ) ;
77
- } ) ;
67
+ componentWillReceiveProps ( nextProps ) {
68
+ const { data, order} = this . state ;
69
+ const { data : nextData , order : nextOrder } = nextProps ;
70
+
71
+ if ( data && nextData && ! shallowEqual ( data , nextData ) ) {
72
+ this . _animateRowsDisappearance ( ( ) => {
73
+ uniqueRowKey . id ++ ;
74
+ this . _areRowsAnimated = false ;
75
+ this . _rowsLayouts = [ ] ;
76
+ this . setState ( {
77
+ data : nextData ,
78
+ containerLayout : null ,
79
+ rowsLayouts : null ,
80
+ order : nextOrder || Object . keys ( nextData )
78
81
} ) ;
79
82
} ) ;
83
+
84
+ } else if ( order && nextOrder && ! shallowEqual ( order , nextOrder ) ) {
85
+ this . setState ( { order : nextOrder } ) ;
86
+ }
80
87
}
81
88
82
- componentWillReceiveProps ( nextProps ) {
83
- const { order } = this . props ;
84
- const { order : nextOrder } = nextProps ;
89
+ componentDidUpdate ( prevProps , prevState ) {
90
+ const { data } = this . state ;
91
+ const { data : prevData } = prevState ;
85
92
86
- if ( order && nextOrder && ! shallowEqual ( order , nextOrder ) ) {
87
- this . setState ( { order : nextOrder } ) ;
93
+ if ( data && prevData && ! shallowEqual ( data , prevData ) ) {
94
+ this . _onLayotRows ( ) ;
88
95
}
89
96
}
90
97
@@ -195,7 +202,7 @@ export default class SortableList extends Component {
195
202
196
203
return (
197
204
< Row
198
- key = { key }
205
+ key = { uniqueRowKey ( key ) }
199
206
ref = { this . _onRefRow . bind ( this , key ) }
200
207
animated = { this . _areRowsAnimated && ! active }
201
208
disabled = { ! sortingEnabled }
@@ -217,6 +224,42 @@ export default class SortableList extends Component {
217
224
} ) ;
218
225
}
219
226
227
+ _onLayotRows ( ) {
228
+ Promise . all ( [ ...this . _rowsLayouts ] )
229
+ . then ( ( rowsLayouts ) => {
230
+ // Can get correct container’s layout only after rows’s layouts.
231
+ this . _container . measure ( ( x , y , width , height , pageX , pageY ) => {
232
+ const rowsLayoutsByKey = { } ;
233
+ let contentHeight = 0 ;
234
+
235
+ rowsLayouts . forEach ( ( { rowKey, layout} ) => {
236
+ rowsLayoutsByKey [ rowKey ] = layout ;
237
+ contentHeight += layout . height ;
238
+ } ) ;
239
+
240
+ this . setState ( {
241
+ containerLayout : { x, y, width, height, pageX, pageY} ,
242
+ rowsLayouts : rowsLayoutsByKey ,
243
+ contentHeight,
244
+ } , ( ) => {
245
+ this . _animateRowsAppearance ( ( ) => ( this . _areRowsAnimated = true ) ) ;
246
+ } ) ;
247
+ } ) ;
248
+ } ) ;
249
+ }
250
+
251
+ _animateRowsAppearance ( onAnimationEnd ) {
252
+ Animated . timing ( this . state . style . opacity , {
253
+ toValue : 1 ,
254
+ } ) . start ( onAnimationEnd ) ;
255
+ }
256
+
257
+ _animateRowsDisappearance ( onAnimationEnd ) {
258
+ Animated . timing ( this . state . style . opacity , {
259
+ toValue : 0 ,
260
+ } ) . start ( onAnimationEnd ) ;
261
+ }
262
+
220
263
_scroll ( animated ) {
221
264
this . _scrollView . scrollTo ( { ...this . _contentOffset , animated} ) ;
222
265
}
0 commit comments