@@ -13,52 +13,50 @@ export const useSprings = (length, props) => {
13
13
const isFn = is . fun ( props )
14
14
15
15
// The controller maintains the animation values, starts and stops animations
16
- const [ controllers , ref ] = useMemo ( ( ) => {
16
+ const [ controllers , setProps , ref , api ] = useMemo ( ( ) => {
17
17
// Remove old controllers
18
18
if ( ctrl . current ) {
19
19
ctrl . current . map ( c => c . destroy ( ) )
20
20
ctrl . current = undefined
21
21
}
22
22
let ref
23
23
return [
24
+ // Recreate the controllers whenever `length` changes
24
25
new Array ( length ) . fill ( ) . map ( ( _ , i ) => {
25
- const ctrl = new Ctrl ( )
26
- const newProps = isFn ? callProp ( props , i , ctrl ) : props [ i ]
26
+ const c = new Ctrl ( )
27
+ const newProps = isFn ? callProp ( props , i , c ) : props [ i ]
27
28
if ( i === 0 ) ref = newProps . ref
28
- return ctrl . update ( newProps )
29
+ return c . update ( newProps )
29
30
} ) ,
31
+ // This updates the controllers with new props
32
+ props =>
33
+ ctrl . current . forEach ( ( c , i ) => {
34
+ c . update ( is . fun ( props ) ? callProp ( props , i , c ) : props [ i ] )
35
+ if ( ! ref ) c . start ( )
36
+ } ) ,
37
+ // The imperative API is accessed via ref
30
38
ref ,
39
+ ref && {
40
+ start : ( ) =>
41
+ Promise . all ( ctrl . current . map ( c => new Promise ( r => c . start ( r ) ) ) ) ,
42
+ stop : finished => ctrl . current . forEach ( c => c . stop ( finished ) ) ,
43
+ get controllers ( ) {
44
+ return ctrl . current
45
+ } ,
46
+ } ,
31
47
]
32
48
} , [ length ] )
33
49
34
- ctrl . current = controllers
35
-
36
- // The hooks reference api gets defined here ...
37
- const api = useImperativeHandle ( ref , ( ) => ( {
38
- start : ( ) =>
39
- Promise . all ( ctrl . current . map ( c => new Promise ( r => c . start ( r ) ) ) ) ,
40
- stop : finished => ctrl . current . forEach ( c => c . stop ( finished ) ) ,
41
- get controllers ( ) {
42
- return ctrl . current
43
- } ,
44
- } ) )
45
-
46
- // This function updates the controllers
47
- const updateCtrl = useMemo (
48
- ( ) => updateProps =>
49
- ctrl . current . map ( ( c , i ) => {
50
- c . update ( isFn ? callProp ( updateProps , i , c ) : updateProps [ i ] )
51
- if ( ! ref ) c . start ( )
52
- } ) ,
53
- [ length ]
54
- )
50
+ // Attach the imperative API to its ref
51
+ useImperativeHandle ( ref , ( ) => api , [ api ] )
55
52
56
53
// Update controller if props aren't functional
57
54
useEffect ( ( ) => {
55
+ ctrl . current = controllers
58
56
if ( mounted . current ) {
59
- if ( ! isFn ) updateCtrl ( props )
57
+ if ( ! isFn ) setProps ( props )
60
58
} else if ( ! ref ) {
61
- ctrl . current . forEach ( c => c . start ( ) )
59
+ controllers . forEach ( c => c . start ( ) )
62
60
}
63
61
} )
64
62
@@ -69,12 +67,12 @@ export const useSprings = (length, props) => {
69
67
} , [ ] )
70
68
71
69
// Return animated props, or, anim-props + the update-setter above
72
- const propValues = ctrl . current . map ( c => c . getValues ( ) )
70
+ const values = ctrl . current . map ( c => c . getValues ( ) )
73
71
return isFn
74
72
? [
75
- propValues ,
76
- updateCtrl ,
73
+ values ,
74
+ setProps ,
77
75
finished => ctrl . current . forEach ( c => c . stop ( finished ) ) ,
78
76
]
79
- : propValues
77
+ : values
80
78
}
0 commit comments