React16.x特性剪辑

本文整理了 React 16.x 出现的耳目一新的概念与 api 以及应用场景。

16.0 Fiber

在 16 之前的版本的渲染过程可以想象成一次性潜水 30 米,在这期间做不了其它事情(Stack Reconciler);

痛点概括:

  • 一次性渲染到底
  • 中途遇到优先级更高的事件无法调整相应的顺序

在 16 版本上, React 带来了 Fiber 的架构, 接着拿上面的潜水例子为例,现在变为可以每次潜 10 米,分 3 个 chunk 进行; chunk 和 chunk 之间通过链表连接; chunk 间插入优先级更高的任务, 先前的任务被抛弃。

开启 Fiber 后,获取异步数据的方法应放到 render 后面的生命周期钩子里(phase 2 阶段)进行, 因为 render 前面的生命周期钩子(phase 1阶段)会被执行多次

注意: 并没有缩短原先组件的渲染时间(甚至还加长了),但用户却能感觉操作变流畅了。

render()

在 React16 版本中 render() 增加了一些返回类型,到目前为止支持的返回类型如下:

  • React elements.
  • Arrays and fragments.
  • Portals.
  • String and numbers.
  • Booleans or null.

render

其中 render() 支持返回 Arrays 能让我们少写一个父节点, 如下所示:

const renderArray = () => [
  <div>A</div>
  <div>B</div>
]

个人认为 render() 支持返回数组完全可以取代 Fragments

Portals(传送门)

将 react 子节点渲染到指定的节点上

案例:实现一个 Modal 组件,demo

另外关于 Portals 做到冒泡到父节点的兄弟节点这个现象, demo, 我想可以这样子实现:如果组件返回是 Portal 对象,则将该组件的父组件的上的事件 copy 到该组件上。其实并不是真的冒泡到了父节点的兄弟节点上。

Error Boundaries

React 16 提供了一个新的错误捕获钩子 componentDidCatch(error, errorInfo), 它能将子组件生命周期里所抛出的错误捕获, 防止页面全局崩溃。demo

componentDidCatch 并不会捕获以下几种错误

  • 事件机制抛出的错误(事件里的错误并不会影响渲染)
  • Error Boundaries 自身抛出的错误
  • 异步产生的错误
  • 服务端渲染

服务端渲染

服务端渲染一般是作为最后的优化手段, 这里浅显(缺乏经验)谈下 React 16 在其上的优化。

在 React 16 版本中引入了 React.hydrate(), 它的作用主要是将相关的事件注水html 页面中, 同时会比较前端生成的 html 和服务端传到前端的 html 的文本内容的差异, 如果两者不一致将前端产生的文本内容替换服务端生成的(忽略属性)。

支持自定义属性

在 React 16 版本中, 支持自定义属性(推荐 data-xxx), 因而 React 可以少维护一份 attribute 白名单, 这也是 React 16 体积减少的一个重要因素。

life cycle

在 React 16.3 的版本中,新加入了两个生命周期:

  • getDerivedStateFromProps(nextProps, prevState): 更加语义化, 用来替代 componentWillMount、componentWillReceiveProps(nextProps);
  • getSnapshotBeforeUpdate(prevProps, prevState): 可以将结果传入 componentDidUpdate 里, 从而达到 dom 数据统一。用来替代 componentWillUpdate()(缺点是 React 开启异步渲染后,componentWillUpdate() 与 componentDidUpdate() 间获取的 dom 会不统一;

16.7 Hooks

在 React 16.7 之前,React 有两种形式的组件,有状态组件(类)和无状态组件(函数)。Hooks 的意义就是赋能先前的无状态组件,让之变为有状态。这样一来更加契合了 React 所推崇的函数式编程。

接下来梳理 Hooks 中最核心的 2 个 api, useStateuseEffect

useState

useState 返回状态和一个更新状态的函数

const [count, setCount] = useState(initialState)

使用 Hooks 相比之前用 class 的写法最直观的感受是更为简洁

function App() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  )
}

useEffect(fn)

在每次 render 后都会执行这个钩子。可以将它当成是 componentDidMountcomponentDidUpdatecomponentWillUnmount 的合集。因此使用 useEffect 比之前优越的地方在于:

  1. 可以避免在 componentDidMount、componentDidUpdate 书写重复的代码;
  2. 可以将关联逻辑写进一个 useEffect;(在以前得写进不同生命周期里);

在上述提到的生命周期钩子之外,其它的钩子是否在 hooks 也有对应的方案或者舍弃了其它生命周期钩子, 后续进行观望。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学 Web 前端

UTF8最好不要带BOM

摘自:http://www.cnblogs.com/findumars/p/3620078.html

1356
来自专栏老司机的简书

CoreText实现图文混排之尺寸估算及文本选择

回头看看,距离CoreText系列首发过去一年也多了,看到第一篇文章即将超越1.3W的点击量老司机也是压力越来越大,毕竟作为瞎逼逼杰出代表的老司机偶尔也要正经一...

872
来自专栏程序员互动联盟

【专业文章】六种常见的HTML5写法误用(二)

四、figure元素的常见错误 figure以及figcaption的正确使用,确实是难以驾驭。让我们来看看一些常见的错误, 不是所有的图片都是figure 上...

2875
来自专栏一个爱瞎折腾的程序猿

看了180分钟的视频,写了半天的代码

清晨,日常打开B站,被首页此视频的标题所吸引,虽一看就是标题党,但还是没能抑制住好奇心。 视频共计60*3分钟,学习到了很多东西。其中后半部分有许多正三观的见...

1602
来自专栏Flutter&Dart

Flutter之WidgetsApp使用详解&与MaterialApp的纠缠

如果对MaterialApp不熟悉,可先看我上一篇文章: Flutter之MaterialApp使用详解

4323
来自专栏性能与架构

将 Redis 作为图数据库

1. 简介 Redis 在 4.0 中正式支持了Module模块系统,使其可以进行丰富的扩展 图数据库的应用越来越广泛,RedisGraph 就是一个 Redi...

4406
来自专栏葬爱家族

Android高级动画(3)

上一篇文章我们讲了Android中的矢量动画,虽然文中展示的Demo并不多,但是相信大家还是体会到了矢量动画的强大。这里再做一个温故总结:

1521
来自专栏菩提树下的杨过

Flash/Flex学习笔记(15):FMS 3.5之远程共享对象(Remote Shared Object)

FMS中的“远程共享对象”可以让多个Client端的flash应用共享同一个全局对象,并且当客户端中的任何一个改变该对象时,系统会自动将该对象回发到FMS服务器...

2108
来自专栏较真的前端

探寻Vue数据双向绑定的底层原理

2675
来自专栏逍遥剑客的游戏开发

Introduction to RenderMonkey

28510

扫码关注云+社区

领取腾讯云代金券