React Native 初尝试之 CNode 社区客户端开发

前端之家收集整理的这篇文章主要介绍了React Native 初尝试之 CNode 社区客户端开发前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

最近踏上了学习使用 React Native 进行客户端开发的征途,因为之前的技术栈一直是 Vue,在大致看了一下React Native 的相关介绍后,感觉有必要首先学习一下ReactJS。再看过相关文档后,以 CNode 社区的 API 上手体验了一下 React 的组件化开发方式,见 cnode-react-App。之后在边看文档边 Google 的过程中,完成了人生中第一次客户端开发。下文中将给出以 CNode 社区为原型进行React Native 开发过程中遇到的问题以及相关思考。

踩坑之路

实践出真知,虽然官方文档已经给出了详细的API以及教程,没有刻骨铭心的踩坑之旅,对于一些问题的理解可能也并不那么透彻。

Github 开源地址

https://github.com/monster1935/cnode-rn-app

App 预览

以下是 App 的部分截图:

已完成功能

目前在现有 CNode Api 的支持下,已经完成以下功能

  • 分类文章显示
  • 文章详情以及文章对应的评论展示,评论包括精彩评论评论
  • 用户的收藏列表、消息列表页
  • 设置、关于、github登录页面(部分页面仅提供了导航占位,后期逐步完善)
  • App 内部连接跳转至webview进行访问,点击更多可以刷新、跳转至浏览器访问
  • 搜索功能,鉴于目前未提供搜索的接口,目前实现为前端按照检索词进行搜索
  • 点击用户头像,跳转用户信息详情页,展示该用户的最近发布以及最近回复
  • 部分操作的权限控制,比如点赞、收藏、收藏列表、信息列表
  • 扫码登录流程
  • 登录后的个人信息展示以及退出功能
  • @H_403_53@

    尚未完成以及待优化功能

    • IOS 下的调试,目前仅仅测试了在 Android 下的表现
    • 回复、发帖功能
    • 添加代码区域的友好展示
    • 导航的跳转,比如点赞或者收藏时,未登录状态下用户需要跳转登录页面登录完成后应定位至点赞、收藏
    • 添加 App 启动页面
    • 用户详情页的动画存在一定问题
    • 异步接口请求的相关控制,组件销毁后,abort相关未完成的请求
    • @H_403_53@

      技术栈

      在开发过程中,用到了社区内较为优秀的一些开源贡献者提供的工具或者包,如下:

      导航的实现 react-navigation

      react-navigation 是 FaceBook 官方推荐使用的导航组件库,据称有着原生般的性能体验效果。使用起来也确实方便,在笔者进行开发的这段时间,react-navigation 的官方文档也进行了更新。官方文档还算详细,还有其他很多功能等待发掘。

      图标 react-native-vector-icons

      第三方的图标库,使用起来比较方便,项目中使用了 Ionicons 的风格。

      全局状态管理 react-redux & redux

      使用了 react-redux 进行全局状态管理,主要涉及到登录后token,用户信息以及文章列表的存储。相关需要登录才能使用的模块也需要获取到全局状态中的token,进行相应的判断。

      html 转 view react-native-htmlview

      涉及到 web 端 html 在 React Native 上的复用问题,因为两端在 布局、组件以及样式上的机制差异,html 完全的转换 view 不是很现实,但是在一定范围内实现转换还是可以的。react-native-htmlview 是目前做的较为优秀的,不过在笔者的使用过程中发现了一些问题,最终还是clone了其代码,又在本地修改解决的,下文会详细解释。

      持久化存储 react-native-storage

      用于登录的token的持久化存储,每次启动 App 后,如果之前曾经登录不必重复登录。其不仅支持 React Native, 也提供了浏览器端的支持

      ActionSheet,用于 webview 中的更多弹出面板 react-native-actionsheet

      目前 app 中的链接均采用 app 内部的 webview 进行显示显示的过程中添加了progress 进度条,并添加了刷新以及在浏览器中打开功能

      二维码扫描组件,基于 react-native-camera 的封装

      基于 react-native-camera 封装的二维码扫码组件,思路借鉴了 react-native-qrcode实现方法

      WebView 中的进度条显示 react-native-progress

      一个更加友好的展示,在网页请求的过程中添加了顶部进度条

      遇到的问题

      1. react-navigation 中使用可滑动的tab view,滑动不生效

      初次使用react-navigation 后,在首页添加react-native-scrollable-tab-view,发现滚动根本不起作用,查阅了相关资料,设置 TabNavigator的 swipeEnabled: false 即可。

      2. 使用 react-native-htmlview 转换 html 字符串至 react native View 的过程,发现图片显示较小

      在使用的过程中发现图片显示异常,查看其 issue,发现有同样的开发者遇到这样的问题。查阅相关资料,React Native Text Inline Image,这篇文章中解释了为什么内嵌于 Text 中的 Image 在 Android 上显示过小的问题。原因在于 React Native 的内部的处理问题,React Native 在这种情况下直接以 图片的原始尺寸进行显示,并未再该尺寸的基础上乘以 图片的 PixelRatio。作者给出了一种解决办法就是封装一个InlineImage 组件,在传入的尺寸属性上手动乘以 PixelRatio

      3. Android 上 Inline Image 通过 Image.getSize() 后无法更新图片大小

      一波未平,一波又起。刚弄明白 Inline Image 显示过小的问题,发现还是无法更加优雅的设置图片的尺寸。原始思路是通过 Image.getSize()后更新图片的尺寸。遗憾的是发现,图片不会更新大小,至今未发现原因。(持续跟进)

      4. 动手修改 react-native-htmlview,完美解决 Image 显示问题

      为了更加优雅的显示文章图片,阅读了 react-native-htmlview 的源码,发现之所以会出现 Inline Image 的问题,主要原因是因为其 Image 是内嵌于 Text 节点,虽然其暴露了 NodeComponent 的 props, 不传的话默认为 Text。问题出现的原因,在于含有 img 标签的父标签被渲染为了 Text。因此在源码中添加了以下内容

      // 节点 后代中如果含有 img ,则该节点渲染为 View
      function _contains(children) {
        for(let i = 0,len = children.length; i < len; i++) {
          if (children[i].type === 'tag' && children[i].name === 'img' || _contains(children[i].children || [])) {
            return true;
          }
        }
        return false;
      }
      ...
      // 标签如果是div 或者 含有img标签的父标签均渲染为View
      if (node.type === 'tag') {
        if (node.name === 'div' || _contains(node.children)) {
          opts.NodeComponent = View;
        } else {
          opts.NodeComponent = Text;
        }
      }

      完美解决了 Image 的显示问题。

      总结

      React Native 的开发如果有 React 的开发经验,上手还是比较快的。主要是熟悉其组件的使用方式以及不同组件之间的区别。目前仅仅实现了一个 Demo 版本,渲染效率以及内存消耗等问题还未优化。后期对React Native 有深入的理解后,会进行相关方面的优化。

      最后

      技术学习的路上已经使用 CNodejs 的 Api 做过了好几个 demo,包括

猜你在找的React相关文章