Short: If duration is 250 or similar value - withTiming callback is called multiple times. That breaks animation.
I use withTiming to detect when animation is finished. And if animation is completed successfully I call callback _onSwipeRight.
const containerStyle = useAnimatedStyle(() => {
return {
height:
rowHeight.value !== undefined
? withTiming(
rowHeight.value,
{
duration: 250,
easing: Easing.out(Easing.ease)
},
(isFinished) => {
console.log(`withTiming is finished? ${isFinished}`);
if (isFinished) {
if (swipeDirection.value === 'left') {
onSwipeLeft();
} else if (swipeDirection.value === 'right') {
console.log(
`SwipableRow: isFinished? ${isFinished}, rowHeight: ${rowHeight.value}`
);
_onSwipeRight && _onSwipeRight();
}
}
}
)
: undefined
};
});
Later inside this _onSwipeRight() I update sqlite database (mark task as _completed_) and unmount component (render undefined instead of task - at this time height of row should be 0)
const [isVisible, setVisible] = useState(true);
const onTaskCompletion = useCallbackOne(
(id: string) => {
console.log(`[onTaskCompletion] complete task ${id}`);
taskRepository.update(id, { isCompleted: true }).then((_) => {
setVisible(false);
});
},
[taskRepository]
);
...
return (
<>
{isVisible ? (
<SwipableTask
id={state.id}
title={state.title}
isCompleted={state.isCompleted}
isTracked={state.isTracked}
trackedSeconds={state.trackedSeconds}
onCompletionButtonPressed={onCompletionButtonPressed}
onTrackButtonPressed={onTrackButtonPressed}
onCompletionSwipe={onTaskCompletion}
/>
) : undefined}
</>
);
If I use duration 150 or 300 for withTiming I see expected behaviour and logging. But for 250 milliseconds
[Thu Sep 17 2020 15:19:49.708] LOG withTiming is finished? true // <-- First call
[Thu Sep 17 2020 15:19:49.710] LOG SwipableRow: isFinished? true, rowHeight: 0
[Thu Sep 17 2020 15:19:49.710] LOG [onTaskCompletion] complete task f2dcb1fa-7531-4b1e-a63c-dbf713589c22
[Thu Sep 17 2020 15:19:49.711] INFO query: UPDATE "tasks" SET "isCompleted" = ? WHERE "id" IN (?) -- PARAMETERS: [1,"f2dcb1fa-7531-4b1e-a63c-dbf713589c22"]
[Thu Sep 17 2020 15:19:49.729] LOG Row: isVisible? false, id [f2dcb1fa-7531-4b1e-a63c-dbf713589c22], title [Task 11]
[Thu Sep 17 2020 15:19:49.987] LOG withTiming is finished? true // <-- Second call
[Thu Sep 17 2020 15:19:49.989] LOG SwipableRow: isFinished? true, rowHeight: 0
[Thu Sep 17 2020 15:19:49.990] LOG [onTaskCompletion] complete task f2dcb1fa-7531-4b1e-a63c-dbf713589c22
[Thu Sep 17 2020 15:19:49.991] INFO query: UPDATE "tasks" SET "isCompleted" = ? WHERE "id" IN (?) -- PARAMETERS: [1,"f2dcb1fa-7531-4b1e-a63c-dbf713589c22"]
[Thu Sep 17 2020 15:19:49.997] LOG Row: isVisible? false, id [f2dcb1fa-7531-4b1e-a63c-dbf713589c22], title [Task 11]
| 250 ms | 300 ms | 150 ms |
![]() |
![]() |
![]() |
Callback is called only once.
Callback might be called multiple times.
Hey @likern
Thanks for your report. It was a bug but this issue is resolved in a newer release. if you still have a problem try a newer version of reanimated. I tested this on alpha.9 and it works.
Most helpful comment
Hey @likern
Thanks for your report. It was a bug but this issue is resolved in a newer release. if you still have a problem try a newer version of reanimated. I tested this on alpha.9 and it works.