我正在尝试在react native中建立聊天,并希望每次到达时都检查是否到达FlatList的底部,因此在打开键盘和用户之前位于列表的末尾(如果她不在列表末尾,我不想向下滚动)。
我当然可以打电话给onEndReached
,但是在加载所有消息时,它只会触发一次。
所以我在编码以下内容,但问自己是否有更好的方法来实现这一点:
我的状态和我的FlatList参考:
const [messageInputFocus, setmessageInputFocus] = useState(false);
const [
messagesListDistanceFromEnd,
setMessagesListDistanceFromEnd,
] = useState(0);
const [messagesListScrollYPos, setMessagesListScrollYPos] = useState(0);
const inboxThreadFlatList = useRef<FlatList>(null);
在输入消息时使用useEffect:
useEffect(() => {
if (messagesListDistanceFromEnd === messagesListScrollYPos) {
inboxThreadFlatList.current?.scrollToEnd({ animated: true });
}
}, [messageInputFocus]);
const onScrollMessagesList = (
event: NativeSyntheticEvent<NativeScrollEvent>
) => {
setMessagesListScrollYPos(event.nativeEvent.contentOffset.y);
};
我的FlatList在底部带有onEndReached和onScroll方法:
<FlatList
data={messages.records}
renderItem={({ item, index }) => {
return (
<View
style={
index === messages.length - 1 ? { paddingBottom: 68 } : {}
}
>
{userMe.id === item.sender ? (
<View
style={[
styles.messageContainer,
styles.messageSentContainer,
]}
>
<View>
<Text
style={[styles.messageText, styles.messageSentText]}
>
{item.message}
</Text>
<View
style={[styles.triangle, styles.triangleSent]}
></View>
</View>
</View>
) : (
<View
style={[
styles.messageContainer,
styles.messageReceivedContainer,
]}
>
<View>
<Text
style={[
styles.messageText,
styles.messageReceivedText,
]}
>
{item.message}
</Text>
<View
style={[styles.triangle, styles.triangleReceived]}
></View>
</View>
</View>
)}
</View>
);
}}
ref={inboxThreadFlatList}
keyExtractor={(item, index) => index.toString()}
initialScrollIndex={messages.length - 1}
onScrollToIndexFailed={(info) => {
const wait = new Promise((resolve) => setTimeout(resolve, 500));
wait.then(() => {
inboxThreadFlatList.current?.scrollToIndex({
index: info.index,
animated: true,
});
});
}}
onEndReached={({ distanceFromEnd }) => {
setMessagesListDistanceFromEnd(distanceFromEnd);
}}
onScroll={onScrollMessagesList}
/>
代码像这样工作。但是再说一次,有没有更好的方法,因为我将滚动位置设置为一个状态并问自己,这是否是性能问题?
答案 0 :(得分:0)
所以有一个原因导致FlatList上的inverted
存在:)
如果FlatList被反转,我可以检查event.nativeEvent.contentOffset.y是否为零,然后像这样设置一次状态:
const onScrollMessagesList = (
event: NativeSyntheticEvent<NativeScrollEvent>
) => {
if (event.nativeEvent.contentOffset.y === 0 && !messagesListScrolledToEnd) {
setMessagesListScrolledToEnd(true);
} else if (messagesListScrolledToEnd) {
setMessagesListScrolledToEnd(false);
}
};
然后检查我的TextInput是否聚焦,如果滚动,则滚动到索引0:
useEffect(() => {
if (messagesListScrolledToEnd) {
scrollToBottom();
}
}, [messageInputFocus]);
const scrollToBottom = () => {
setTimeout(() => {
inboxThreadFlatList.current?.scrollToIndex({
animated: true,
index: 0,
});
}, 50);
};
我希望这对任何人都有帮助。