深夜学习之 ReactNative 打开聊天窗口时,聊天记录如何始终保持底部

最近开发客服聊天功能,发现个没有思路的一个问题,如标题所述

1. 背景描述

现在有一个开始聊天界面,里面有个 FlatList 会先加载最近30条聊天记录,有文字、视频、图片,媒体文件还要请求宽高比动态给 width,height,点进来后先请求 API 拿到聊天记录(后面做了本地缓存)然后传给 FlatList 数据开始渲染,问题来了,渲染是从第一条开始的,也就是从顶部开始顺着往下依次渲染

2. 如何保持在最底部

聊天界面反向与传统列表,是最新的在最底部,历史是往上滑的,所以要一直 ref.current.scrollToEnd({animated: false}) 吗,以下我折腾过的几个思路

  1. setInterval 不停的 scrollToEnd(),直到用户触摸到屏幕我就不滚了,微信打开群聊消息也会这样,因为要加载媒体的宽高,页面自然就会跳动,– 但是要做分页,第一次不能加载太多,不然不停的滚啊滚
  2. 我不想滚🥹,假如我有50个聊天窗口(已经做了聊天记录缓存在本地),我就 map 50 个 FlatList,没打开某个聊天之前直接开始渲染,然后一直循环[1]的操作,做 display: blockdisplay: hidden,当然50个窗口默认 display:hidden,命中到哪个窗口我就 display: block 出来,– 折腾半天发现根本行不通,数据流,数据指向,数据刷新逻辑写了三个Context都不够用,太特么复杂了…
  3. 既然从上往下渲染,先把数据按照逆序排序,把 FlatList 旋转 180° 🤔,内容区域再 -180°不就正回来了🤔,往上滚不刚好可以触发滚动到底部加载更多🥰!! –实测可行,一点问题没有,就是滚动条会到左边,有强迫症或者强制需求的这个不是难事就不赘述了。

3. 放一些第[3]步成功的参考代码

<FlatList
      ref={listRef}
      data={list ?? []}
      className={'px-3 rotate-180'} //  用的 nativewind 库直接写 className
      onEndReached={() => console.log('触发滚动到底部,加载更多')}
      onEndReachedThreshold={0.2}
      renderItem={({item, index}) => <TouchableOpacity activeOpacity={1} onPress={() => setTaped(true)} className={'-rotate-180'}>
        {item.user_id === user?.id ? <BubbleRight data={item} /> : <BubbleLeft data={item} />}
      </TouchableOpacity>}
    />

深夜学习之 ReactNative 打开聊天窗口时如何总是滚动到底部

本作品采用《CC 协议》,转载必须注明作者和本文链接
yybawang
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 1

那个滑动条可以隐藏吧,这个思路好啊 :+1:

6个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!