按下底部栏选项卡并且我们位于 FlatList 的顶部时,我无法找到刷新 FlatList 的正确方法。
我确实使用
useScrollToTop
成功到达了FlatList的顶部,我也设法重新获取数据,但它不是我想要的。
import { useScrollToTop } from '@react-navigation/native';
const flatlistRef = useRef<FlatList>(null);
useScrollToTop(flatlistRef);
这会滚动到 FlatList 的顶部,但是:
我正在使用 React-Navigation 作为底部选项卡 (
"@react-navigation/bottom-tabs": "^6.5.16"
)
有什么想法吗?
谢谢
找到了解决方案 - 可能是更好的答案,如果可以随时回复!
const [isRefreshing, setIsRefreshing] = useState<boolean>(false);
const flatlistRef = useRef<FlatList>(null);
const scrollPositionRef = useRef(0);
const refetchControl = async () => {
setIsRefreshing(true);
await refetchAPIEndpoint();
setIsRefreshing(false);
};
const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
scrollPositionRef.current = event.nativeEvent.contentOffset.y;
};
const scrollToTop = async () => {
if (scrollPositionRef.current === 0) {
await refetchControl();
flatlistRef.current?.scrollToOffset({ offset: 0 });
} else {
flatlistRef.current?.scrollToOffset({ offset: 0 });
}
}
useScrollToTop(
useRef({ scrollToTop }),
);
return (
<FlatList
...
ref={flatlistRef}
onScroll={handleScroll}
refreshControl={<RefreshControl refreshing={isRefreshing} onRefresh={refetchControl} />}
/>
);
不太明白
useScrollToTop(useRef({ scrollToTop }))
这个,但它有效 - 请随意解释!
由于您想要做的不仅仅是在选项卡聚焦时滚动到顶部,因此您应该放弃使用
useScrollToTop
,而只使用 useFocusEffect。每当当前选项卡成为焦点时就会调用该钩子。您可以在此挂钩中刷新数据并滚动到平面列表的顶部(demo):
import { useState, useEffect, useCallback, useRef } from 'react';
import {
View,
Text,
StyleSheet,
FlatList,
ActivityIndicator,
} from 'react-native';
import { useFocusEffect } from '@react-navigation/native';
import useCountSeconds from './useCountSeconds';
import ListItem from './ListItem';
export default function HomeScreen({ navigation }) {
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const flatlistRef = useRef();
// debug value used to show when last fetch was made
const [lastRefresh, setLastRefresh] = useState(Date.now());
// counts seconds between lastRefresh and current time
const seconds = useCountSeconds(lastRefresh);
const refreshData = useCallback(async () => {
setIsLoading(true);
try {
// get sample data
const data = await fetch('https://dummyjson.com/products');
const json = await data.json();
setData(json.products);
// update lastRefresh
setLastRefresh(Date.now());
setIsLoading(false);
} catch (err) {
console.log(err);
setIsLoading(false);
}
}, []);
useFocusEffect(
// must wrap function in callback to avoid
// calling this effect alot
useCallback(() => {
console.log('Home screen focused');
refreshData();
flatlistRef.current?.scrollToOffset({ offset: 0 });
}, [refreshData])
);
return (
<View style={styles.container}>
{isLoading && <ActivityIndicator size="large" />}
<Text>Refreshed: {seconds}s ago</Text>
<View style={styles.listContainer}>
<FlatList
ref={flatlistRef}
data={data}
renderItem={(props) => <ListItem {...props} />}
keyExtractor={(item) => item.id}
numColumns={2}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justigyContent: 'center',
},
listContainer: {
flex: 1,
margin: 10,
padding: 5,
},
});