React Native FlatList 用于聊天应用程序以即时显示最新消息

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

我正在 React Native 中开发一个聊天应用程序,并面临在 FlatList 中渲染许多消息的问题。我想在列表底部显示最新消息,类似于 WhatsApp 和 Messenger 的工作方式。我尝试了多种方法,但没有一种方法能够提供我想要的流畅体验:

  1. (方法01)倒排列表:此方法也不适用于大量消息,因为到达那里需要时间,并且用户可以在该屏幕上随时来来去去,因此用户不能等待那么久更长。
   <FlatList
     inverted
     contentContainerStyle={{
       flexGrow: 1,
       flexDirection: 'column-reverse',
     }}
     ref={flatListRef}
     data={chat}
     keyExtractor={keyExtractor}
     renderItem={renderMessage}
     ItemSeparatorComponent={renderSeperator}
   />
  1. (方法02)初始索引: 使用initialScrollIndex需要固定的项目高度,而我没有,所以这种方法对我的情况不可行,这是我使用的方法,但
    ITEM_HEIGHT
    不会固定,所以它会在最大消息中花费大量性能.
 <FlatList
    ref={flatListRef}
    data={chat}
    keyExtractor={keyExtractor}
    renderItem={renderMessage}
    ItemSeparatorComponent={renderSeperator}
    initialScrollIndex={chat.length - 1}
    getItemLayout={(_, index) => {
      return {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index};
    }}
  />
  1. (方法03)滚动到底部内容大小更改: 当有1000条消息时,将scrollToBottom与onContentSizeChange结合使用也需要时间才能到达底部。
  const scrollToBottom = (isAnimated = false) => {
    if (flatListRef.current) {
      flatListRef.current.scrollToEnd({animated: isAnimated});
    }
  };

  return (
    <FlatList
      ref={flatListRef}
      data={chat}
      keyExtractor={keyExtractor}
      renderItem={renderMessage}
      ItemSeparatorComponent={renderSeperator}
      onContentSizeChange={() => scrollToBottom(false)} // Doesn't matter if i use animated or not
    />
  );

我正在寻找一种方法来优化 FlatList,即使有大量消息,也能立即显示最新消息,没有任何延迟。我愿意接受诸如在用户向上滚动时删除旧消息之类的建议,但我不确定如何有效地实现这一点。任何实现流畅聊天体验的指导或替代方法将不胜感激。

react-native optimization react-native-flatlist flatlist
1个回答
0
投票

使用

inverted
道具,它起作用了。有一个简单的技巧,我也必须使用
reverse()
函数来反转消息数组,而且我还必须使用scrollToTop 函数才能滚动到底部。这是我制作聊天屏幕应用程序的方法,外观非常流畅。


const DUMMY_CHAT = new Array(10000).fill(null).map((_, i) => ({message: i.toString()}))

const flatListRef = useRef();
  const [chat, setChat] = useState(DUMMY_CHAT);

  const renderMessage = ({item, index}) => <ChatMsg {...item} />;
  const renderSeperator = useCallback(() => <Spacer height={24} />, []);
  const keyExtractor = useCallback((_, i) => i.toString(), []);

  // This function will now actually scroll to the bottom.
  // Now you can use this function suppose sending new message to scroll to the bottom.
  const scrollToTop = (isAnimated = false) => {
    if (flatListRef.current) {
      flatListRef.current.scrollToOffset({offset: 0, animated: isAnimated});
    }
  };

  return (
    <FlatList
      inverted
      ref={flatListRef}
      data={chat.reverse()}
      istHeaderComponent={ChatInternalHeader}
      keyExtractor={keyExtractor}
      renderItem={renderMessage}
      ItemSeparatorComponent={renderSeperator}
    />
  );
© www.soinside.com 2019 - 2024. All rights reserved.