react-native-slider icon indicating copy to clipboard operation
react-native-slider copied to clipboard

Thumb flickers and jumps when slider value is set programmatically

Open abrahamgalue opened this issue 6 months ago • 11 comments

Environment

info Fetching system and libraries information...
System:
  OS: Windows 11 10.0.22631
  CPU: "(12) x64 AMD Ryzen 5 7530U with Radeon Graphics         "
  Memory: 14.63 GB / 31.35 GB
Binaries:
  Node:
    version: 22.16.0
    path: ~\AppData\Local\fnm_multishells\16944_1750346856565\node.EXE
  Yarn:
    version: 1.22.22
    path: C:\Program Files (x86)\Yarn\bin\yarn.CMD
  npm:
    version: 10.9.2
    path: ~\AppData\Local\fnm_multishells\16944_1750346856565\npm.CMD
  Watchman: Not Found
SDKs:
  Android SDK:
    API Levels:
      - "34"
      - "35"
    Build Tools:
      - 30.0.3
      - 34.0.0
      - 35.0.0
    System Images:
      - android-34 | Google Play Intel x86_64 Atom
      - android-35 | Google Play Intel x86_64 Atom
    Android NDK: Not Found
  Windows SDK:
    AllowDevelopmentWithoutDevLicense: Enabled
    AllowAllTrustedApps: Enabled
    Versions:
      - 10.0.26100.0
IDEs:
  Android Studio: AI-243.24978.46.2431.13208083
  Visual Studio: Not Found
Languages:
  Java: 17.0.12
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli":
    installed: 18.0.0
    wanted: ^18.0.0
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.76.9
    wanted: ^0.76.9
  react-native-windows: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

info React Native v0.80.0 is now available (your project is running on v0.76.9).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.80.0
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.76.9&to=0.80.0
info For more info, check out "https://reactnative.dev/docs/upgrading?os=windows".
  • are you using the new architecture? Yes

  • which version of react & react-native are you using? 18.3.1

Description

I'm using Expo 52 and using a simple Slider that follows the official documentation, and the slider thumb just jumps and causes weird UI behavior. I'm using an Expo Development Build and testing it on an Android device. Here's the simple example:

Reproducible Demo

export const LightLevel = () => {
	const [value, setValue] = useState(10)
	return (
		<>
			<Text>Light: {value && +value.toFixed(3)}%</Text>
			<Slider
				style={{ width: 200 }}
				step={1}
				minimumValue={0}
				maximumValue={100}
				value={value}
				onValueChange={setValue}
				minimumTrackTintColor={'#00629A'}
				maximumTrackTintColor={'#979EA4'}
			/>
		</>
	)
}

abrahamgalue avatar Jun 19 '25 15:06 abrahamgalue

@abrahamgalue
debounce((val) => { setValue(val); }, 50);

panna-oo avatar Jun 20 '25 07:06 panna-oo

This only delays the bug, but does not solve the problem.

abrahamgalue avatar Jun 27 '25 01:06 abrahamgalue

I'm facing the same issue with the thumb flickering and jumping when setting the value programmatically.

As a temporary workaround, I’ve implemented a check using isSliderTouched to ensure that setValue is only triggered during user interaction (onTouchStart / onTouchEnd). This seems to prevent the flickering/jumping behavior for now:

export const LightLevel = () => {
  const [value, setValue] = useState(10);
  const [isSliderTouched, setIsSliderTouched] = useState(false);

  return (
    <>
      <Text>Light: {value && +value.toFixed(3)}%</Text>
      <Slider
        style={{ width: 200 }}
        step={1}
        minimumValue={0}
        maximumValue={100}
        value={value}
        onValueChange={(value) => {
          if (!isSliderTouched) {
            return;
          }
          setValue(value);
        }}
        minimumTrackTintColor={'#00629A'}
        maximumTrackTintColor={'#979EA4'}
        onTouchStart={() => setIsSliderTouched(true)}
        onTouchEnd={() => setIsSliderTouched(false)}
      />
    </>
  );
};

While this doesn't fix the root cause, it at least stops the slider from jumping when the value is updated externally.

IlyaPasternakAmitech avatar Jul 08 '25 08:07 IlyaPasternakAmitech

For now, in my app, I'm using a similar approach. For my status, I use Zustand since there are several parameters that are going to be changed, but here's an example.

import { View } from 'react-native'
import { useDevicesActions } from '@/store/devicesStore'
import { Text } from '@/components/ui/text'
import Slider from '@react-native-community/slider'

function LightLevel({ deviceId, brightness }) {
	const { handleDeviceBrightness } = useDevicesActions()

	return (
	  <View>
		<Text className='px-8 text-start text-modal-secondary'>
			LIGHT {brightness}%
		</Text>
		<Slider
			style={{ width: 240 }}
			step={1}
			lowerLimit={0}
			upperLimit={100}
			minimumValue={0}
			maximumValue={100}
			value={brightness}
			onSlidingComplete={(value) => handleDeviceBrightness(deviceId, value)}
			thumbTintColor={'#D9D9D9'}
			minimumTrackTintColor={'#D9D9D9'}
			maximumTrackTintColor={'#538297'}
		/>
	</View>
	)
}

The only issues I've encountered are that the brightness value doesn't update in real time, and in the React inspector with the React Developer Tools, the slider seems to re-render many times when you move it to change its value. This is unlike when using a similar approach to the one in the documentation, which seems more optimized, but causes these flickering and jumps.

For now, I'll leave it with this approach until I get more information or an official solution.

abrahamgalue avatar Jul 08 '25 16:07 abrahamgalue

Hi, thanks for reporting. I have tried reproducing that on both provided setup and our example which runs on React 19.0 and React Native 79 but without much success. Could you maybe record video or give some more context ? For me setting value programatically works fine, I do not see any flickering, at least not on the emulator.

draggie avatar Jul 17 '25 10:07 draggie

I'm having the same issue on Android emulator. I'm using React 19.0.0 and RN 0.79.5. The flickering happens when I press the slider, move it and release while still moving. If I release while stopped, it does not happen.

https://github.com/user-attachments/assets/751db7bf-869e-4f4e-9d4c-c027242d52c5

Here is a video:

meleffendi avatar Jul 20 '25 15:07 meleffendi

Hi, thanks for reporting. I have tried reproducing that on both provided setup and our example which runs on React 19.0 and React Native 79 but without much success. Could you maybe record video or give some more context ? For me setting value programatically works fine, I do not see any flickering, at least not on the emulator.

@draggie Of course, as I said before I am using an Expo build for development and I run the project with the bunx expo start command on a physical device with Android 15, using React 18.3.1 and react-native 0.76.9, with Expo 52, because in Expo 53 there is a problem with the Supabase library that I use for authentication so I hope they fix it to update.

Here you have a little video to see the behavior I am getting:

https://github.com/user-attachments/assets/a5789d9b-bee7-43a7-b88d-7f3b9a9c8b53

abrahamgalue avatar Jul 20 '25 18:07 abrahamgalue

Facing same issue on Android emulator, react-native v0.77.2. As a workaround for now using onSlidingComplete instead of onValueChange

dayanch-n avatar Aug 05 '25 11:08 dayanch-n

+1 We are currently facing the same issue on a real Android (OnePlus 6T Android 11)

petitTrung avatar Aug 06 '25 23:08 petitTrung

I think I figured out, lets take a look at the documentation

  /**
   * Write-only property representing the value of the slider.
   * Can be used to programmatically control the position of the thumb.
   * Entered once at the beginning still acts as an initial value.
   * The value should be between minimumValue and maximumValue,
   * which default to 0 and 1 respectively.
   * Default value is 0.
   *
   * This is not a controlled component, you don't need to update the
   * value during dragging.
   */
  value?: number;

So I guess in your case @abrahamgalue , the value attribute should the initial value that should be passed to the component. We do not need to reset every time the value attribute when user drags the Slider, i.e when the onValueChange function gets called

petitTrung avatar Aug 07 '25 00:08 petitTrung

I think I figured out, lets take a look at the documentation

/**

  • Write-only property representing the value of the slider.
  • Can be used to programmatically control the position of the thumb.
  • Entered once at the beginning still acts as an initial value.
  • The value should be between minimumValue and maximumValue,
  • which default to 0 and 1 respectively.
  • Default value is 0.
  • This is not a controlled component, you don't need to update the
  • value during dragging. */ value?: number; So I guess in your case @abrahamgalue , the value attribute should the initial value that should be passed to the component. We do not need to reset every time the value attribute when user drags the Slider, i.e when the onValueChange function gets called

Yes, I read that part of the documentation. My goal with the Slider is to change the brightness intensity in my application (of anything, for example), and I want the 'Brightness: 62%' value to update accordingly as the user slides the slider.

That's my goal, and when the user stops interacting (lifts their finger from the slider), that value is saved in a database, for example.

I was trying to look for examples, but I couldn't find many in the documentation beyond this temporary solution I implemented, which doesn't reflect the slider value in real time, only when the user stops interacting.

abrahamgalue avatar Sep 19 '25 13:09 abrahamgalue