由于setState在状态下更改了滑块的值并且在实际滑块移动之后发生,所以滑块滞后了很多时间。我已经看到人们使用防弹跳功能来解决此问题,但效果不佳,我觉得必须有一个更加实用的解决方案。消除抖动只会使问题不那么明显,也不能从根本上解决问题。
有什么想法吗?
<!-- language: lang-js -->
<Slider
value={this.state.someValue}
maximumValue={this.state.sliderMaximumValue}
minimumValue={0}
onValueChange={(someValue) => this.setState({someValue})}
/>
答案 0 :(得分:1)
我建议使用onSlidingComplete
而不是onValueChange
,因为它仅在用户操作结束时才设置状态(并刷新视图)。
编辑 如DOCS所述,这不会影响您对滑块的数字显示值的更新:
这不是受控组件,您不需要更新值 在拖动过程中。
答案 1 :(得分:1)
只需通过 not 即可将value
道具传递到<Slider />
,即可实现所需的目标。因此,像这样:
<!-- language: lang-js -->
<Slider
// value={this.state.someValue} // commented out :D
maximumValue={this.state.sliderMaximumValue}
minimumValue={0}
onValueChange={(someValue) => this.setState({someValue})}
/>
就是这样! :D
但是! 如果需要不断显示滑块的变化值(根据需要),可以执行以下操作:
在组件中为一个实际状态创建2个状态。一个显示,另一个是要传递给<Slider />
的实际值(在这种情况下,您无需注释掉value
道具)。
我有一个组件,其中必须显示不断变化的滑块值,而滑块不会滞后。所以我这样做了:
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)}
/>
因此,您需要通过value
道具传递实际状态,但仅更新onSlidingComplete
。另一方面,在每次更改时更新display
状态,即onValueChange
,并将其显示在某些文本组件中。
我希望我能说清楚。如果没有,请询问,我会详细说明。 :)
答案 2 :(得分:0)
使用已发布的代码,很难说出要渲染的其他东西以及组件中的滑块,然后在每次值更改时调用setState都是一件坏事,它触发了许多渲染的方式,这就是为什么它滞后了因为它需要重渲染。
解决方案:
1)如果不需要在UI上反映任何内容,则可以执行onValueChange = {(someValue)=> this.state.sliderValue = someValue},这不会触发渲染,但会保留状态上的滑块值。
2)将滑块提取到其自己的纯组件中,并以这种方式将滑块状态保持为该组件,当您更改滑块设置状态时,将仅重新渲染滑块组件的一部分,而不是整个屏幕。
希望这对您有所帮助。
答案 3 :(得分:0)
我们可以像下面这样使用 onTouchStart 和 onTouchEnd:
import React, { useState } from 'react';
import { View } from 'react-native';
import Slider from '@react-native-community/slider';
const MySlider = () => {
const [value, setValue] = useState(0);
const [isTouchEnded, setIsTouchEnded] = useState(false);
return (
<View>
<Slider
minimumValue={0}
maximumValue={10}
value={isTouchEnded ? value : 0}
onValueChange={(e) => setValue(e)}
onTouchEnd={() => setIsTouchEnded(true)}
onTouchStart={() => setIsTouchEnded(false)}
/>
</View>
);
};
export default MySlider;