Skip to content

Commit 7113be6

Browse files
committed
wip: round 4
1 parent 923a1c1 commit 7113be6

File tree

1 file changed

+32
-36
lines changed

1 file changed

+32
-36
lines changed

src/useSprings.js

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,52 +13,48 @@ export const useSprings = (length, props) => {
1313
const isFn = is.fun(props)
1414

1515
// The controller maintains the animation values, starts and stops animations
16-
const [controllers, ref] = useMemo(() => {
17-
// Remove old controllers
18-
if (ctrl.current) {
19-
ctrl.current.map(c => c.destroy())
20-
ctrl.current = undefined
21-
}
16+
const [controllers, setProps, ref, api] = useMemo(() => {
2217
let ref
2318
return [
19+
// Recreate the controllers whenever `length` changes
2420
new Array(length).fill().map((_, i) => {
25-
const ctrl = new Ctrl()
26-
const newProps = isFn ? callProp(props, i, ctrl) : props[i]
21+
const c = new Ctrl()
22+
const newProps = isFn ? callProp(props, i, c) : props[i]
2723
if (i === 0) ref = newProps.ref
28-
return ctrl.update(newProps)
24+
return c.update(newProps)
2925
}),
26+
// This updates the controllers with new props
27+
props =>
28+
ctrl.current.forEach((c, i) => {
29+
c.update(is.fun(props) ? callProp(props, i, c) : props[i])
30+
if (!ref) c.start()
31+
}),
32+
// The imperative API is accessed via ref
3033
ref,
34+
ref && {
35+
start: () =>
36+
Promise.all(ctrl.current.map(c => new Promise(r => c.start(r)))),
37+
stop: finished => ctrl.current.forEach(c => c.stop(finished)),
38+
get controllers() {
39+
return ctrl.current
40+
},
41+
},
3142
]
3243
}, [length])
3344

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-
)
45+
// Attach the imperative API to its ref
46+
useImperativeHandle(ref, () => api, [api])
5547

5648
// Update controller if props aren't functional
5749
useEffect(() => {
50+
if (ctrl.current !== controllers) {
51+
if (ctrl.current) ctrl.current.map(c => c.destroy())
52+
ctrl.current = controllers
53+
}
5854
if (mounted.current) {
59-
if (!isFn) updateCtrl(props)
55+
if (!isFn) setProps(props)
6056
} else if (!ref) {
61-
ctrl.current.forEach(c => c.start())
57+
controllers.forEach(c => c.start())
6258
}
6359
})
6460

@@ -69,12 +65,12 @@ export const useSprings = (length, props) => {
6965
}, [])
7066

7167
// Return animated props, or, anim-props + the update-setter above
72-
const propValues = ctrl.current.map(c => c.getValues())
68+
const values = ctrl.current.map(c => c.getValues())
7369
return isFn
7470
? [
75-
propValues,
76-
updateCtrl,
71+
values,
72+
setProps,
7773
finished => ctrl.current.forEach(c => c.stop(finished)),
7874
]
79-
: propValues
75+
: values
8076
}

0 commit comments

Comments
 (0)