React Native ScrollView调用scrollTo报错:undefined is not a function(Hermes引擎)
问题:点击ScrollView导航圆点触发scrollTo时报错TypeError: undefined is not a function
我尝试用useRef实现点击底部圆点按钮时,自动将ScrollView滚动到对应的幻灯片视图。点击按钮调用scrollTo()方法时,出现错误TypeError: undefined is not a function,使用的JS引擎是Hermes。想确认是useRef和scrollTo的使用方式有误,还是node_modules的问题?
完整的ImageSlider组件代码如下:
import { height } from 'deprecated-react-native-prop-types/DeprecatedImagePropType' import { onChange } from 'deprecated-react-native-prop-types/DeprecatedTextInputPropTypes' import React , {useState,useRef} from 'react' import { StyleSheet, View , Text , ScrollView , Pressable , Image, Dimensions , TouchableOpacity} from 'react-native' const WIDTH = Dimensions.get('window').width const HEIGHT = Dimensions.get('window').height const ImageSlider = ({slides}) => { const refScrollview = useRef() const [currentIndex,setCurrentIndex] = useState(0) // console.log(slides[currentIndex].banner) const [imageActive,setImageActive] = useState(1) const onChange = (nativeEvent) =>{ if(nativeEvent){ const slide = Math.ceil(nativeEvent.contentOffset.x / nativeEvent.layoutMeasurement.width) if(slide != imageActive){ console.log(slide) setImageActive(slide) console.log(refScrollview.current) } } } return( <View style={{flex:1}}> <ScrollView ref={refScrollview} // onContentSizeChange={(contentWidth, contentHeight)=> {refScrollview.current.scrollToEnd({animated: true})}} onScroll={({nativeEvent}) => onChange(nativeEvent)} showsHorizontalScrollIndicator={false} pagingEnabled horizontal style={styles.wrap} > { slides.map((e,index)=> // <Text>{e.banner}</Text> <View style={{flex:1}} key={index}> <Image source={e.banner} style={[styles.wrap]} > </Image> <Image source={e.bannerFace} style={styles.bannerFace} > </Image> </View> ) } </ScrollView> <View style={styles.wrapDot}> { slides.map((e,index)=> <TouchableOpacity key={index} style={imageActive == index ? styles.lineActive : styles.lineOnly} onPress={() => { refScrollview.current.scrollTo()}}> </TouchableOpacity> ) } </View> </View> ) } let styles = StyleSheet.create({ backgroundImage: { flex:1, width: null, height: null, // width: 400, // height: 400, // resizeMode: 'cover', }, bannerFace:{ position:'absolute', bottom:0, right:0, flex: 1, width: 150, height: 150, resizeMode: 'contain' }, wrap:{ width:WIDTH, height:'100%' }, wrapDot:{ position:'absolute', bottom:20, left:50, flexDirection:'row', alignSelf:'center' }, lineOnly:{ padding:5, width:70, borderRadius:15, borderColor:'#CECECE', backgroundColor:'#CECECE', marginHorizontal:5 }, lineActive:{ padding:5, width:70, borderRadius:15, borderColor:'#FFF', backgroundColor:'#FFF', marginHorizontal:5 } }) export default ImageSlider
问题原因与修复方案
这是useRef和scrollTo方法的使用方式错误,和node_modules无关,具体问题点及修复如下:
useRef初始化不规范
初始化useRef时应传入null作为初始值,明确指向组件实例:const refScrollview = useRef(null)scrollTo方法缺少必要参数
React Native的ScrollView.scrollTo()方法需要传入包含目标位置的配置对象,且要处理ref可能为null的情况(避免组件未挂载时调用报错)。对于水平滚动的场景,需要计算对应幻灯片的x轴偏移量:
修改底部圆点的onPress回调:onPress={() => { if (refScrollview.current) { refScrollview.current.scrollTo({ x: index * WIDTH, animated: true }) setImageActive(index) // 同步更新当前激活的圆点状态 } }}初始状态不匹配索引规则
imageActive初始值设为1,但幻灯片索引从0开始,会导致初始状态下第一个幻灯片的圆点未被正确激活,建议改为:const [imageActive,setImageActive] = useState(0)onScroll中的slide计算优化
原代码用Math.ceil计算当前幻灯片索引,可能导致滚动过程中索引频繁变化,建议改用Math.floor,更符合分页滚动的预期:const slide = Math.floor(nativeEvent.contentOffset.x / nativeEvent.layoutMeasurement.width)
总结
所有问题均属于代码使用方式错误,修正上述几点后即可正常实现点击圆点滚动到对应幻灯片的功能,无需调整node_modules。
内容的提问来源于stack exchange,提问作者Jzx Naga
相关产品推荐
相关产品推荐

