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
相关产品推荐
相关产品推荐

