React Native FlatList 分页

问题描述 投票:0回答:1

我想对我的聊天实现分页,因此当用户向上滚动时,会加载更多消息。目前我面临一个问题,当我向上滚动时,会加载更多消息,但“视图”会捕捉到 FlatList 的顶部,并且它只会加载更多消息,因为它认为用户滚动到了那里。加载新消息时,我无法使视图保持原样。

最初加载 15 条消息,向上滚动时,还会加载 15 条消息并添加到聊天中。

代码:



const Chat = ({ route }) => {

  const { user } = useContext(UserContext)

  const navigation = useNavigation()

  const { conversationId, friend: initialFriend } = route.params

  const flatListRef = useRef(null)

  const [isAtBottom, setIsAtBottom] = useState(true)

  const [isLoadingMore, setIsLoadingMore] = useState(false)

  const {

    friend, conversation, newMessage,

    setNewMessage, inputHeight, setInputHeight,

    loading, sendMessage, loadMoreMessages

  } = useChat(user, conversationId, initialFriend)



  const handleLoadMoreMessages = () => {

    if (loading || isAtBottom || isLoadingMore) return

    setIsLoadingMore(true)

    setTimeout(() => {

      loadMoreMessages()

      setIsLoadingMore(false)

    }, 300)

  }



  if (loading) {

    return (

      <View style={styles.loadingContainer}>

        <ActivityIndicator size="large" color="#0000ff" />

      </View>

    )

  }



  return (

    <ImageBackground source={defaultBackgroundPicture} style={styles.container}>

      <CustomNavBar navigation={navigation} friend={friend}/>

      <View style={styles.content}>

        <View style={styles.header}>

        </View>

        {conversation && <FlatList

          ref={flatListRef}

          key={conversationId}

          data={conversation.messages}

          keyExtractor={item => item && item._id ? item._id : uuid.v4()}

          renderItem={({ item }) => <MessageItem item={item} user={user} />}

          onScroll={({ nativeEvent }) => {

            const isCloseToBottom = nativeEvent.layoutMeasurement.height + nativeEvent.contentOffset.y >= nativeEvent.contentSize.height - 50

            setIsAtBottom(isCloseToBottom)

            if (nativeEvent.contentOffset.y < 20) {

              handleLoadMoreMessages()

            }

          }}

          onContentSizeChange={() => {

            if (isAtBottom) flatListRef.current.scrollToEnd({ animated: false })

          }}

        />}

        <View style={styles.inputContainer}>

          <TextInput

            style={[styles.input, { height: Math.max(35, inputHeight) }]}

            value={newMessage}

            onChangeText={text => setNewMessage(text)}

            placeholder="Type a message..."

            multiline

            onContentSizeChange={(event) => {

              setInputHeight(event.nativeEvent.contentSize.height)

            }}

          />

          <Pressable style={styles.sendButton} onPress={() => {

            if (newMessage.length !== 0) sendMessage()

          }}>

            <Icon name="send" size={24} color="white" />

          </Pressable>

        </View>

      </View>

    </ImageBackground>



  )

}


我一直在尝试使用平面列表的 onScroll 和 onContentSizeChange 属性。

reactjs react-native expo react-native-flatlist
1个回答
0
投票

我通过将数据获取逻辑切换为使用react-query并在FlatList中使用inverted和onEndReached属性来解决这个问题。

        <FlatList
      inverted
      ref={flatListRef}
      data={messagesData.pages.flatMap(page => {
        return page.conversation.messages
      })}
      keyExtractor={item => item && item._id ? item._id : uuid.v4()}
      renderItem={({ item }) => <MessageItem item={item} user={user} />}
      onEndReached={handleEndReached}
      onEndReachedTreshold={0.5}
    />
© www.soinside.com 2019 - 2024. All rights reserved.