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

React Native ScrollView Web端滚动异常:缩放抖动、停止后无法滚动

React Native Web端ScrollView滚动异常修复

问题描述

在React Native中使用ScrollView实现内容超出屏幕时的垂直滚动,但Web端垂直缩小屏幕时,滚动条持续显示并隐藏(抖动),停止缩小后滚动条消失且无法滚动。已尝试重启应用和Metro,问题未解决。

相关代码

SignUpScreen.tsx

...
return (
    <View style={[styles.mobileContainer,styles.mobileScreen,]} > //flex:1
      <ScrollView contentContainerStyle={{flex:1}} //flex:1
        style={GlobalStyle.formContainer}
        >
        <View >  //wrapper of the whole content
          <View style={styles.signupImage}>
            <Image source={images.Signup} style={styles.image} />
          </View>
          <Title title={'sign up'} style={{marginBottom:SIZES.xLarge}} />  
          
          <View style={styles.inputContainer}>
            <Controller
              name="fullName"
              control={control}
              render={({ field: { onChange, onBlur, value, ref } }) =>  
                <PaperInput
                  readOnly={false}
                  returnKeyType="next"
                  isValid={value===''?false:errors.fullName?false:true}
                  rightIcon={value!==undefined&&errors.fullName===null
                    ?<True width={SIZES.medium} height={SIZES.medium} />
                    : undefined}
                  leftIcon={<Name color={COLORS.gray} width={SIZES.medium} height={SIZES.medium} 
                   />}
                  placeholder={'full name'}
                  onChangeText={(value: any) => onChange(value) }
                  value={value}
                  
                />

              }
            />
            <ErrorMessage errors={errors} name="fullName"  render={({ message }) => 
                <Error message={message} />} />
          </View>
          //....rest of my controlled input 

          <View style={styles.inputContainer}>
            {<PrimaryButton value={signupButtonText} 
                disabled ={false} onPress={handleSubmit(onSubmit)}
                icon={signupButtonText=== 'signing up...'
                ?<ActivityIndicator size={SIZES.medium} color={COLORS.white}
                  style={{ marginRight:SIZES.medium}} />
                :undefined
                }
            />}
          </View>
          <View style={styles.navigate}>
            <Text style={TextStyle.navigateText}></Text>
          </View>
        </View>
      </ScrollView>
    </View>
  )
}

export default SignUpScreen

styles.ts

export const styles = StyleSheet.create({

 mobileContainer: { 
      flex:1,
      //height:'100%',
      flexWrap: 'nowrap',
      paddingVertical:SIZES.xSmall,
      paddingHorizontal:SIZES.medium,
      backgroundColor: COLORS.white,
      justifyContent:'flex-start',
      alignItems:'center',
      },

 formContainer:{
        flex:1,
        width:'90%',
        maxWidth:300,
},
inputContainer:{
   flex:1,
   marginBottom:SIZES.large ,
  },
signupImage:{
    flex:1,
    justifyContent:'center',
    alignItems:'center',
    marginBottom:42,
  //  marginTop:SIZES.large

  },
  image:{
     width:250,
     height:160,
     
  },
    })

问题原因

ScrollView的contentContainerStyle={{flex:1}}强制内容容器占满父容器高度,当屏幕缩小导致内容实际高度超过容器时,flex布局的拉伸逻辑与ScrollView的滚动判定逻辑冲突,引发滚动条反复切换显示状态,最终导致滚动功能失效。

修复方案

  1. 移除contentContainerStyle的flex:1设置:让内容容器高度由内部元素自然撑开,ScrollView才能正确判断内容是否超出容器高度。
  2. 明确ScrollView的滚动配置:添加scrollEnabled={true}确保滚动功能始终可用,可选设置showsVerticalScrollIndicator={true}强制显示滚动条(根据需求调整)。
  3. 确保ScrollView占满可用高度:保留ScrollView样式中的flex:1,确保它继承父容器的可用空间。

修改后的核心代码

return (
  <View style={[styles.mobileContainer, styles.mobileScreen]}>
    <ScrollView
      style={[GlobalStyle.formContainer, { flex: 1 }]}
      scrollEnabled={true}
      showsVerticalScrollIndicator={true}
    >
      <View>
        {/* 原有内部内容保持不变 */}
      </View>
    </ScrollView>
  </View>
)

同时建议移除内部内容wrapper View的flex属性(如果有设置),避免不必要的高度拉伸。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:44:54