标签: FlashList

  • 近期 React Native + Expo 研发笔记

    近期 React Native + Expo 研发笔记

    整理一下近期开发 React Native App 的经验,以 tips 为主,写下来确保将来不会掉在同样的坑里。能够直接从官方文档查到的我就不写了,这里主要记录我踩到的坑。

    技术栈

    先说技术栈,我们目前的技术栈主要是:

    1. React Native v0.74.5,版本受 Expo 限制
    2. Expo v51.0.38
    3. NativeWind 用来写样式,蛮舒服的
    4. Supabase + expo-sqlite + AsyncStorage 用来做各种存储
    5. expo-apple-authentication + @react-native-google-signin/google-signin 用来 SSO
    6. expo-av 用来录音
    7. react-native-sse 用来流式传输

    选择 Expo 是因为 React Native 官方推荐,搭起来环境才发现没那么必要……不过配都配好了,就懒得重新搞了。实际用了之后,感觉还不错,大部分功能都更好用,尤其是各种组件比原始组件要好很多。所以推荐大家需要新组建时先看 Expo SDK:docs.expo.dev/versions/latest/sdk/ 大部分都比原生组件好。实在没有再去找其它 React Native 组件。

    Expo

    Expo 不是必须的,但还是蛮值得使用的。尤其是对 App router 这种基于文件系统的路由体系很熟悉的开发者来说,Expo 很值得。

    Expo 提供构建体系 eas,不过免费版每个月只能构建 15 次 iOS,不够用。所以大部分时间还是本地构建。构建之后,无法直接右键安装,但是可以通过 XCode Devices 安装。

    使用 Expo 需要注意环境变量和组件配置。因为对 .env 的修改、环境配置(app.json)、Logo、字体等的配置不一定会实时生效。所以修改这些不受 React Native 控制之后的东西,都先 prebuild + clean cache,然后再打包。或者直接在项目里手动搜索并修改也可以。

    手机上安装 Expo App 之后可以在 React Native 和 Expo 的网站上预览效果。其中 Android App 可以直接启动摄像头扫二维码;iOS app 没有启动摄像头的选项,我一直以为没法用,后来才发现,直接用照相机扫描二维码,就可以在 Expo 里打开了。

    NativeWind

    NativeWind 让我们可以在 React Native 里使用 TailwindCSS 和 className,非常舒服,非常推荐。

    不过 NativeWind 也有问题。有些组件的 className 不会直接应用在外层容器上,比如 expo-image。而如果不设置 widthheight 的话,<Image> 就不会显示,这会导致我们无法正常使用这个组件。

    还有一些组件,它们由多个视觉组件组成,所以样式也需要分层配置,就有一些诸如 containerWrapperStyle 的属性。这样的组件也无法通过 className 来配置样式。所以我们使用的时候还是要多小心。如果组件渲染不符合预期,那么就看看组件如何应用样式。

    Expo Image

    Expo Image 比起 React Native Image 强很多:

    • 支持 WebP
    • 支持缓存
    • 支持 object-fitobject-position 填充
    • 支持一些我还没有用到的新特性

    非常推荐。但是不支持 NativeWind,请大家记得直接操作其 style 属性。

    FlashList

    <FlashList> 是 Shopify 开发的列表组件,针对大量内容高速滚动做了优化。它提供兼容 <FlatList> 的接口,可以无痛替换,推荐使用。

    使用的时候,需要注意滚动方向。比如 Twitter 这种最新的在上面,就是默认滚动;如果是聊天窗口这样最新的在下面,就要 inverted=true。同时还要注意,inverted=true 之后,Header Footer 的位置也要对调。

    Expo AV

    Expo AV 可以用来录音和播放音频。我们用它来实现 STT。将来会尝试原生 STT。

    需要注意的点不多,主要就是切换应用时,录音会自动停止,并且无法继续。所以我们需要侦听事件,并且做出相应的处理。

    渲染效率

    React Native 不支持非常高频的渲染,比如 Streaming output。在网页上没问题,在 RN 里就会报错:too many renderings。所以,我们需要适当缓存数据,减少渲染频率。我目前是 32 token 渲染一次。

    将来会尝试用 reanimate 之类的库来渲染文字,看看能否得到更好的效果。

    总结

    其实最近遇到的问题很多都跟 React 有关,不过考虑到 React 开发者恐怕不会认为这些“问题”是问题,所以还是写一些文档里找不到但是可能会踩到的坑吧。

    希望对大家有用,如果大家对 React,React Native,React Native Expo 开发感兴趣、有问题的话,欢迎留言讨论。