EnjoyChan

8 天前

移动端项目快速升级 react 16 指南

本文作者:IMWeb EnjoyChan 原文出处:IMWeb社区 未经同意,禁止转载

背景

考虑到移动端性能,腾讯企鹅辅导移动端项目使用了更为轻量的 preact(7KB) 及其对应配套 preact-router 等, 考虑到 preact 对 react 的兼容不全、生态远不如 react 等问题,且 react 16 相当吸引人的特性包括:

  1. 体积减少
    • react is 5.3 kb (2.2 kb gzipped), down from 20.7 kb (6.9 kb gzipped).
    • react-dom is 103.7 kb (32.6 kb gzipped), down from 141 kb (42.9 kb gzipped).
    • react + react-dom is 109 kb (34.8 kb gzipped), down from 161.7 kb (49.8 kb gzipped).
  2. 错误处理, 可通过定义一个组件专门捕获错误,当页面部分组件报错时兼容,更友好的用户体验
  3. lazy 提供动态 import 组件,Suspense 实现代码分割
  4. hook 的出现
  5. 更好的服务端渲染
  6. ...

升级操作

  1. 更新 package.json 包引用, 升级 react 版本及相关配套如 react-router
  2. webpack config 文件更新 alias 及更新 preact 在项目中引用
  3. 删除 react-addons-perf , react 16 不支持该 addon, 改建议使用 performance 能力
  4. 引入对应 polifill, 由于我们的用户还有许多使用 android 4.4 以下的手机,根据 react 官方, react 16 依赖 map 、 set, 所以引入 core-js 的对应 polyfill, 确保 polyfill 在 react 引用前被引用
  5. 开启严格模式,运行项目,在浏览器 console 面板中可查看到项目可能的报错及 warning, 并附带有 react 相关链接关于如何修改

fix 问题点

  1. state 相关
    1. react 16 不允许 state 未声明时使用,需声明 this.state = {};
    2. setState 问题,关于 state 的更新,react 16 与之前的异步更新方式并无不同,在生命周期钩子函数、react 事件中会收集所有的 setState 并进行 patch update, 但遇到了有些组件的方法表现并不一致,而是每执行到 setState 则立即更新,这个需要注意社区组件提供回调方法的执行机制,如我们项目中使用到 react-slick,afterChange 方法并没有收集两次 setState 一起更新, 所以需要注意代码顺序
      1. state 引用,当通过闭包的形式使用 state 时,在之前的 preact 下,闭包函数使用的 state 为最新的 state 引用,升级为 react 之后,引用的是旧的 state, 更改前后:
  2. react-router 问题
  3. 升级后的 react-router 的 组件只能有一个子节点,将多节点收归在一个 div 标签下解决
    1. React-router 的 props 传递,如果组件要获取路径匹配,需通过 matches 字段,为了快速 fix,可以通过 HOC 形式包裹组件直接传递 {…props.matches}, 或者通过 decorator 的形式
  4. 组件需要明确返回内容或者 null, 对 return exp1 && exp2 形式的返回需注意 可更改为:
  5. 在 preact 结合 react-redux 中,组件生命周期钩子函数如果执行多个 dispatch, 会集合每个 dispatch 之后再触发生命周期钩子执行,升级 react 16 后,钩子函数的每个 dispatch action 都会单独走生命周期
  6. refs, 函数式组件(无状态组件) 使用 refs 会导致 refs 内容为空,更改为使用 React.fowardRef

升级后的 react, 我们又可以愉快地使用各种新特性、更优雅的写代码了,更重要的是利用这些新特性提升页面性能、提供更好的用户体验,以下为官方图,下次再写一篇升级 react 16 之后性能相关文章

0条评论

    您需要 注册 一个IMWeb账号或者 才能进行评论。