Skip to content

Commit 92df880

Browse files
authored
Incubator.Slider - fix 'value' updates (#2994)
* Incubator.Slider - fix 'value' updates and container flex * remove flex * Update src/incubator/Slider/index.tsx Adding GradientSlider comment
1 parent 4d5bbf6 commit 92df880

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

src/incubator/Slider/index.tsx

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import _ from 'lodash';
2-
import React, {ReactElement, useImperativeHandle, useCallback, useMemo, useEffect} from 'react';
2+
import React, {ReactElement, useImperativeHandle, useCallback, useMemo, useEffect, useRef} from 'react';
33
import {StyleSheet, AccessibilityRole, StyleProp, ViewStyle, GestureResponderEvent, LayoutChangeEvent, ViewProps, AccessibilityProps} from 'react-native';
44
import {useSharedValue, useAnimatedStyle, runOnJS, useAnimatedReaction, withTiming} from 'react-native-reanimated';
55
import {forwardRef, ForwardRefInjectedProps, Constants} from '../../commons/new';
@@ -222,6 +222,8 @@ const Slider = React.memo((props: Props) => {
222222
const end = useSharedValue(0);
223223
const defaultThumbOffset = useSharedValue(0);
224224
const rangeThumbOffset = useSharedValue(0);
225+
226+
const didValueUpdate = useRef(false);
225227

226228
const thumbBackground: StyleProp<ViewStyle> = useMemo(() => [
227229
{backgroundColor: disabled ? disabledThumbTintColor : thumbTintColor}
@@ -235,37 +237,45 @@ const Slider = React.memo((props: Props) => {
235237
const _thumbStyle = useSharedValue(StyleUtils.unpackStyle(customThumbStyle || defaultThumbStyle, {flatten: true}));
236238
const _activeThumbStyle = useSharedValue(StyleUtils.unpackStyle(activeThumbStyle, {flatten: true}));
237239

238-
useEffect(() => {
239-
if (!thumbStyle) {
240-
_thumbStyle.value = StyleUtils.unpackStyle(defaultThumbStyle, {flatten: true});
241-
}
242-
// eslint-disable-next-line react-hooks/exhaustive-deps
243-
}, [defaultThumbStyle, thumbStyle]);
244-
245-
useImperativeHandle(forwardedRef, () => ({
246-
reset: () => reset()
247-
}));
248-
249-
const reset = () => {
250-
setInitialPositions(trackSize.value.width);
251-
onReset?.();
252-
};
253-
254-
const setInitialPositions = (trackWidth: number) => {
240+
const setInitialPositions = useCallback((trackWidth: number) => {
255241
validateValues(props);
256242

257-
const defaultThumbPosition = getOffsetForValue(
258-
useRange ? initialMinimumValue : value,
243+
const defaultThumbPosition = getOffsetForValue(useRange ? initialMinimumValue : value,
259244
trackWidth,
260245
minimumValue,
261246
maximumValue);
262247
const rangeThumbPosition = getOffsetForValue(initialMaximumValue, trackWidth, minimumValue, maximumValue);
263248
defaultThumbOffset.value = defaultThumbPosition;
264249
rangeThumbOffset.value = useRange ? rangeThumbPosition : trackWidth;
250+
}, [value]);
251+
252+
const reset = () => {
253+
setInitialPositions(trackSize.value.width);
254+
onReset?.();
265255
};
266256

257+
useImperativeHandle(forwardedRef, () => ({
258+
reset: () => reset()
259+
}));
260+
261+
useEffect(() => {
262+
didValueUpdate.current = true;
263+
setInitialPositions(trackSize.value.width);
264+
}, [value, setInitialPositions]);
265+
266+
useEffect(() => {
267+
if (!thumbStyle) {
268+
_thumbStyle.value = StyleUtils.unpackStyle(defaultThumbStyle, {flatten: true});
269+
}
270+
// eslint-disable-next-line react-hooks/exhaustive-deps
271+
}, [defaultThumbStyle, thumbStyle]);
272+
267273
const onValueChangeThrottled = useCallback(_.throttle(value => {
268-
onValueChange?.(value);
274+
if (!didValueUpdate.current) { // NOTE: fix for GradientSlider (should be removed after fix in the GradientSlider component): don't invoke onChange when slider's value changes to prevent updates loop
275+
onValueChange?.(value);
276+
} else {
277+
didValueUpdate.current = false;
278+
}
269279
}, 200), [onValueChange]);
270280

271281
const onRangeChangeThrottled = useCallback(_.throttle((min, max) => {
@@ -343,7 +353,7 @@ const Slider = React.memo((props: Props) => {
343353
}
344354
}
345355
}
346-
}, []);
356+
}, [disabled, useRange, rangeGap, shouldBounceToStep]);
347357

348358
const _onSeekStart = () => {
349359
'worklet';

0 commit comments

Comments
 (0)