Open alexstrat opened 3 years ago
After some time of investigation, I realized that, when the animation is no-op (ie position
is already at toValue
), there is a race condition between resetting isManuallySetValue
to 0 when the animation finished and reanimated being able to catch the change of isManuallySetValue
at onChange(isManuallySetValue)
:
With animation=timing
:
# tap "Snap to 1"
set isManuallySetValue to 1 in #snapTo
onChange(isManuallySetValue) actions are run
animation is run
[...a moment]
set isManuallySetValue to 0 in finished state of the animation
onChange(isManuallySetValue) actions are run
# tap "Snap to 1"
set isManuallySetValue to 1 in #snapTo
onChange(isManuallySetValue) actions are run
animation is run <- no op, instantaneous
set isManuallySetValue to 0 in finished state of the animation
onChange(isManuallySetValue) actions are run
# tap "Snap to 2"
set isManuallySetValue to 1 in #snapTo
onChange(isManuallySetValue) actions are run
animation is run
[...a moment]
set isManuallySetValue to 0 in finished state of the animation
onChange(isManuallySetValue) actions are run
With animation=spring
:
# tap "Snap to 1"
set isManuallySetValue to 1 in #snapTo
onChange(isManuallySetValue) actions are run
animation is run
[...a moment]
set isManuallySetValue to 0 in finished state of the animation
onChange(isManuallySetValue) actions are run
# tap "Snap to 1"
set isManuallySetValue to 1 in #snapTo
animation is run <- no op, instantaneous
set isManuallySetValue to 0 in finished state of the animation
# tap "Snap to 2"
set isManuallySetValue to 1 in #snapTo
animation is run <- no op, instantaneous because `this.destSnapPoint` was not properly updated because onChange(isManuallySetValue) actions are never run
set isManuallySetValue to 0 in finished state of the animation
I was able to debunk the race condition with this but it's not clean:
diff --git a/src/index.tsx b/src/index.tsx
@@ -557,7 +558,7 @@ export class ScrollBottomSheet<T extends any> extends Component<Props<T>> {
cond(eq(this.destSnapPoint, snapPoints[0]), [
set(this.dragWithHandle, 0),
]),
- set(this.isManuallySetValue, 0),
+ call([], () => this.isManuallySetValue.setValue(0)),
set(this.manualYOffset, 0),
stopClock(clock),
this.prevTranslateYOffset,
An other solution would be to use only imperative methods rather than relying on onChange
see https://github.com/rgommezz/react-native-scroll-bottom-sheet/pull/54
Current Behavior
With this modification of the "bank" example:
To reproduce:
Expected Behavior
Expected:
You can verify the expected behavior if you remove the prop
animationType="spring"
Your Environment