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

React Native中SectionList实现上下滚动按钮功能失败求助

解决SectionList中按钮控制滚动的报错问题

问题说明

尝试将FlatList的按钮控制上下滚动逻辑迁移到SectionList时,点击按钮会触发报错,无法实现预期的滚动效果。

错误原因

SectionList的ref指向的是组件本身的实例,而非内部的滚动视图。与FlatList不同,SectionList需要通过getScrollResponder()方法获取内部滚动响应器后,才能调用scrollToOffset、scrollToEnd这类滚动控制方法。直接通过组件ref调用滚动方法会因找不到对应方法而报错。

修正后的代码

import React from "react";
import {
  StyleSheet,
  Text,
  View,
  SafeAreaView,
  SectionList,
  StatusBar,
  TouchableOpacity,
  Image,
} from "react-native";

const DATA = [
  {
    title: "主菜",
    data: ["披萨", "汉堡", "烩饭"],
  },
  {
    title: "配菜",
    data: ["薯条", "洋葱圈", "炸虾仁"],
  },
  {
    title: "饮品",
    data: ["水", "可乐", "啤酒"],
  },
  {
    title: "甜点",
    data: ["芝士蛋糕", "冰淇淋"],
  },
];

const Item = ({ title }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

const App = () => {
  const listRef = React.useRef(null);
  const [contentVerticalOffset, setContentVerticalOffset] = React.useState(0);

  const upButtonHandler = () => {
    // 获取滚动响应器后调用滚动到顶部方法
    listRef.current?.getScrollResponder()?.scrollToOffset({ offset: 0, animated: true });
  };

  const downButtonHandler = () => {
    // 获取滚动响应器后调用滚动到底部方法
    listRef.current?.getScrollResponder()?.scrollToEnd({ animated: true });
  };

  return (
    <SafeAreaView style={styles.container}>
      <SectionList
        sections={DATA}
        keyExtractor={(item, index) => item + index}
        renderItem={({ item }) => <Item title={item} />}
        renderSectionHeader={({ section: { title } }) => (
          <Text style={styles.header}>{title}</Text>
        )}
        onScroll={(event) => {
          setContentVerticalOffset(event.nativeEvent.contentOffset.y);
        }}
        ref={listRef}
      />

      <TouchableOpacity
        activeOpacity={0.5}
        onPress={downButtonHandler}
        style={styles.downButtonStyle}
      >
        <Image
          source={{
            uri: "https://raw.githubusercontent.com/AboutReact/sampleresource/master/arrow_down.png",
          }}
          style={styles.downButtonImageStyle}
        />
      </TouchableOpacity>
      <TouchableOpacity
        activeOpacity={0.5}
        onPress={upButtonHandler}
        style={styles.upButtonStyle}
      >
        <Image
          source={{
            uri: "https://raw.githubusercontent.com/AboutReact/sampleresource/master/arrow_up.png",
          }}
          style={styles.upButtonImageStyle}
        />
      </TouchableOpacity>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: StatusBar.currentHeight,
    marginHorizontal: 16,
  },
  item: {
    backgroundColor: "#f9c2ff",
    padding: 20,
    marginVertical: 8,
  },
  header: {
    fontSize: 32,
    backgroundColor: "#fff",
  },
  title: {
    fontSize: 24,
  },
  upButtonStyle: {
    position: "absolute",
    width: 50,
    height: 50,
    alignItems: "center",
    justifyContent: "center",
    right: 30,
    bottom: 70,
  },
  upButtonImageStyle: {
    resizeMode: "contain",
    width: 30,
    height: 30,
  },
  downButtonStyle: {
    position: "absolute",
    width: 50,
    height: 50,
    alignItems: "center",
    justifyContent: "center",
    right: 30,
    top: 70,
  },
  downButtonImageStyle: {
    resizeMode: "contain",
    width: 30,
    height: 30,
  },
});

export default App;

关键修改点

  • 在按钮点击事件中,先通过listRef.current?.getScrollResponder()获取SectionList内部的滚动响应器实例
  • 使用可选链操作符?.避免组件未挂载时的空引用报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:35:28