You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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无关,具体问题点及修复如下:

  1. useRef初始化不规范
    初始化useRef时应传入null作为初始值,明确指向组件实例:

    const refScrollview = useRef(null)
    
  2. scrollTo方法缺少必要参数
    React Native的ScrollView.scrollTo()方法需要传入包含目标位置的配置对象,且要处理ref可能为null的情况(避免组件未挂载时调用报错)。对于水平滚动的场景,需要计算对应幻灯片的x轴偏移量:
    修改底部圆点的onPress回调:

    onPress={() => {
      if (refScrollview.current) {
        refScrollview.current.scrollTo({
          x: index * WIDTH,
          animated: true
        })
        setImageActive(index) // 同步更新当前激活的圆点状态
      }
    }}
    
  3. 初始状态不匹配索引规则
    imageActive初始值设为1,但幻灯片索引从0开始,会导致初始状态下第一个幻灯片的圆点未被正确激活,建议改为:

    const [imageActive,setImageActive] = useState(0)
    
  4. onScroll中的slide计算优化
    原代码用Math.ceil计算当前幻灯片索引,可能导致滚动过程中索引频繁变化,建议改用Math.floor,更符合分页滚动的预期:

    const slide = Math.floor(nativeEvent.contentOffset.x / nativeEvent.layoutMeasurement.width)
    

总结

所有问题均属于代码使用方式错误,修正上述几点后即可正常实现点击圆点滚动到对应幻灯片的功能,无需调整node_modules。

内容的提问来源于stack exchange,提问作者Jzx Naga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:55:25