Since setState changes the value of the slider in the state and happens after the actual slider movement, the slider lags quite a bit. I've seen people use debouncing to fix this, but it doesn't work so well and I feel like there must be a more pragmatic solution. Debouncing simply makes the issue less apparent, it doesn't fix it at the root.
Any ideas?
<!-- language: lang-js -->
<Slider
value={this.state.someValue}
maximumValue={this.state.sliderMaximumValue}
minimumValue={0}
onValueChange={(someValue) => this.setState({someValue})}
/>
You can achieve what you want by simply not passing in the value
prop to the <Slider />
. So, like this:
<!-- language: lang-js -->
<Slider
// value={this.state.someValue} // commented out :D
maximumValue={this.state.sliderMaximumValue}
minimumValue={0}
onValueChange={(someValue) => this.setState({someValue})}
/>
That's it! :D
But! If you need to constantly display a changing value of the slider, (as I needed) you can do this:
Create 2 states in your component for one actual piece of state. One to display, and one to be the actual value to be passed to the <Slider />
(and in this case you don't need to comment out the value
prop).
I had a component where I had to display the constantly changing slider value, without the slider lagging. So I did this:
const [displayTotalQuantity, setDisplayTotalQuantity] = useState(FUEL_AMOUNT_MINIMUM);
const [totalQuantity, setTotalQuantity] = useState(FUEL_AMOUNT_MINIMUM);
<Text> {displayTotalQuantity} </Text>
<Slider
style={slider.baseStyles}
step={STEP}
value={totalQuantity}
minimumValue={MINIMUM}
maximumValue={MAXIMUM}
minimumTrackTintColor={mainColors.irisBlue}
maximumTrackTintColor={mainColors.sliderMaxTintGray}
thumbTintColor={mainColors.irisBlue}
onSlidingComplete={value => setTotalQuantity(value)}
onValueChange={value => setDisplayTotalQuantity(value)}
/>
So, you need to pass the actual state through the value
prop, but update it only onSlidingComplete
. On the other hand, update the display
state on each change, i.e. onValueChange
and display it in some text component.
I hope I made myself clear. If not, ask and I will elaborate. :)
With your posted code it's hard to say what's going on if you are rendering bunch of other stuff along with your slider in your component then calling setState on every value change is a bad thing it's triggering way to many renders that's why it's lagging because it has to much to re-render.
solutions:
1) if you don't need to reflect any thing on UI you can do onValueChange={(someValue) => this.state.sliderValue = someValue} this won't trigger render but will preserve slider value on state.
2) extract slider to it's own pure component and keep slider state to that component this way when you change slider set state will re-render only slider component part instead of whole screen.
hope this helps you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With