Thumb flickers and jumps when slider value is set programmatically
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
debounce((val) => {
setValue(val);
}, 50);
This only delays the bug, but does not solve the problem.
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.
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.
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.
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:
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
Facing same issue on Android emulator, react-native v0.77.2. As a workaround for now using onSlidingComplete instead of onValueChange
+1 We are currently facing the same issue on a real Android (OnePlus 6T Android 11)
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
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
valueattribute should theinitial valuethat should be passed to the component. We do not need to reset every time thevalueattribute when user drags the Slider, i.e when theonValueChangefunction 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.