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

React Native点击按钮滚动至指定组件的实现问题求助

解决方案

1. 修复自定义组件的Ref传递

函数组件默认不支持直接接收ref属性,必须用React.forwardRef将父组件的ref传递到内部的滚动容器:

修改Architecture组件:

import React, { ReactNode, forwardRef } from "react";
import {
  ScrollView,
  SafeAreaView,
  View,
  Dimensions,
} from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import tw from "../../tw-rn";

interface ArchitectureProps {
  children: ReactNode;
}

// 使用forwardRef传递ref到内部ScrollView
const Architecture = forwardRef<ScrollView, ArchitectureProps>(({ children }, ref) => {
  const { height } = Dimensions.get("window");
  return (
    <View>
      <SafeAreaView>
        <KeyboardAwareScrollView>
          <ScrollView
            nestedScrollEnabled
            ref={ref}
          >
            <View style={tw`pb-25`}>{children}</View>
          </ScrollView>
        </KeyboardAwareScrollView>
      </SafeAreaView>
    </View>
  );
});

export default Architecture;

2. 动态获取目标组件位置并滚动

不要用固定的y:200,通过目标组件的ref获取实际布局坐标,再调用滚动方法:

修改页面代码:

import React, { useRef, useCallback } from "react";
import { Button, View, findNodeHandle, UIManager, Platform, ScrollView } from "react-native";
import Architecture from "./Architecture";
import VeterinarianPet from "./VeterinarianPet";

const YourComponent = () => {
  const scrollViewRef = useRef<ScrollView>(null);
  const section3Ref = useRef<View>(null);

  const scrollToSection = useCallback(() => {
    if (!scrollViewRef.current || !section3Ref.current) return;

    // 跨平台获取组件布局位置
    const measureCallback = (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => {
      scrollViewRef.current?.scrollTo({ y: pageY, animated: true });
    };

    if (Platform.OS === 'android') {
      UIManager.measure(findNodeHandle(section3Ref.current), measureCallback);
    } else {
      section3Ref.current.measure(measureCallback);
    }
  }, []);

  return (
    <Architecture ref={scrollViewRef}>
      <Button title="Scroll to Section 3" onPress={scrollToSection} />
      {/* 可添加占位内容测试滚动效果 */}
      <View style={{ height: 500, backgroundColor: '#f0f0f0' }} />
      <View ref={section3Ref}>
        <VeterinarianPet />
      </View>
    </Architecture>
  );
};

export default YourComponent;

3. 优化滚动容器嵌套(可选)

当前Architecture组件嵌套了KeyboardAwareScrollView和ScrollView,双重滚动容器可能导致冲突。如果KeyboardAwareScrollView已满足键盘适配需求,可移除内层ScrollView,直接将ref传递给KeyboardAwareScrollView:

修改后的Architecture组件:

import React, { ReactNode, forwardRef } from "react";
import {
  SafeAreaView,
  View,
  Dimensions,
} from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import tw from "../../tw-rn";

interface ArchitectureProps {
  children: ReactNode;
}

const Architecture = forwardRef<KeyboardAwareScrollView, ArchitectureProps>(({ children }, ref) => {
  const { height } = Dimensions.get("window");
  return (
    <View>
      <SafeAreaView>
        <KeyboardAwareScrollView
          ref={ref}
          nestedScrollEnabled
        >
          <View style={tw`pb-25`}>{children}</View>
        </KeyboardAwareScrollView>
      </SafeAreaView>
    </View>
  );
});

export default Architecture;

此时页面中scrollViewRef的类型需改为KeyboardAwareScrollView,它同样支持scrollTo方法。

关键说明

  • Ref传递正确性:必须通过forwardRef让自定义组件接收并传递ref,否则scrollViewRef.current会是无效值。
  • 动态坐标:固定y值无法适配不同布局,通过measure获取组件实际坐标是可靠方案。
  • 滚动容器冲突:多个滚动容器嵌套会导致滚动事件混乱,尽量只保留一个核心滚动容器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:06:10