Skip to content

Commit ae697c6

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

File tree

1 file changed

+29
-31
lines changed

1 file changed

+29
-31
lines changed

src/useSprings.js

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,52 +13,50 @@ 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(() => {
16+
const [controllers, setProps, ref, api] = useMemo(() => {
1717
// Remove old controllers
1818
if (ctrl.current) {
1919
ctrl.current.map(c => c.destroy())
2020
ctrl.current = undefined
2121
}
2222
let ref
2323
return [
24+
// Recreate the controllers whenever `length` changes
2425
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]
2728
if (i === 0) ref = newProps.ref
28-
return ctrl.update(newProps)
29+
return c.update(newProps)
2930
}),
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
3038
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+
},
3147
]
3248
}, [length])
3349

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])
5552

5653
// Update controller if props aren't functional
5754
useEffect(() => {
55+
ctrl.current = controllers
5856
if (mounted.current) {
59-
if (!isFn) updateCtrl(props)
57+
if (!isFn) setProps(props)
6058
} else if (!ref) {
61-
ctrl.current.forEach(c => c.start())
59+
controllers.forEach(c => c.start())
6260
}
6361
})
6462

@@ -69,12 +67,12 @@ export const useSprings = (length, props) => {
6967
}, [])
7068

7169
// 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())
7371
return isFn
7472
? [
75-
propValues,
76-
updateCtrl,
73+
values,
74+
setProps,
7775
finished => ctrl.current.forEach(c => c.stop(finished)),
7876
]
79-
: propValues
77+
: values
8078
}

0 commit comments

Comments
 (0)