一.资源

  1. Recoil英文网
  2. Recoil中文网
  3. github

    二.Recoil是什么

    Recoil是 Facebook 公司出的数据流管理方案,是一个 React 状态管理库,目前还处于实验阶段,但是Facebook内部已经有部分在使用,由于Recoil可以使用React内部的调度机制,因此对于React开发者来说,使用recoil是未来的趋势。

但 Recoil 和 Redux 一样,并不代表 React 官方数据流管理方案,因此不用带着官方光环去看它

三. 传统的状态管理方式

Redux

image.png

mobx

image.png

**

四.动机

出于兼容性和简便性的考虑,React中最好使用状态管理库。目前React中常见状态库有redux、mobx,但是这些状态管理库,也许也不是那么”友好“:

  • 只能通过状态提升至公共祖先来共享状态,但可能导致一颗巨大的树重新渲染。
  • 上下文(context)只能存储一个值,而不能存储一组不确定的值,且每个值都有自己的使用者(consumers)。
  • 这两种方式都很难将组件树的叶子节点(使用状态的地方)与组件树的顶层(状态必须存在的地方)进行代码分拆。
    在保持 API 以及语义和行为尽可能接近 React 的同时,Recoil对上述问题做了改进。

五. Recoil做了什么

Recoil

image.png

Recoil 定义了一个正交有向图(directed graph orthogonal),并附加在 React 树中。状态的变化从该图的根(我们称之为 atom)开始,通过纯函数(我们称之为 selector)的方式传入组件。具体方式如下:

  • Recoil创建了无模板(boilerplate-free) API,其共享状态与 React 内部的状态拥有相同的 get/set 接口(如果需要,也可以使用 reducer 等)。
  • Recoil有与并发模式(Concurrent Mode)及其他 React 新特性兼容的可能性。
  • 状态的定义是增量及分布式的,从而可以进行代码拆分。
  • 可以用派生数据替换状态,而无需修改使用它的组件。
  • 派生数据可以在同步与异步间切换,而无需修改使用它的组件。
  • Recoil可以将导航(navigation)视为一等公民(first-class concept),甚至可以对链接中的状态进行编码。
  • 以向后兼容的方式持久保存整个应用程序的状态很容易,因此持久化保存的状态可以在应用程序更改之后继续存在。

六.为什么要使用Recoil

简练并保持与 React 一致

Recoil 的行为方式和原理与 React 完全一致。将其使用到你的应用程序中能够获得快速且灵活的状态共享。

数据流图

派生数据和异步查询均采用纯函数和高效的订阅方式实现。

应用程序全局监听

通过监听应用程序中所有状态的变化来实现持久化存储、路由、时间旅行调试或撤消,并且不会影响代码拆分。

持续提高性能

优化内存管理、更高效地支持大数据的状态等

支持Concurrent Mode

目前已发布的版本,已经提供了一些实验性的 api 以支持 React 该特性。会与 React 合作,以高效支持 Concurrent Model。而目前其他状态管理库都无法支持 Concurrent Mode

什么是 Concurrent Mode

对于 React 的复杂组件在执行一次 Render 时,耗时是会比较长的,由于 JS 是单线程的,这时候就出现了页面”假死”的情况。在 React 渲染过程中,是无法再去响应用户的操作的,比如按钮点击等。这就造成了很不好的用户体验。
为了解决该问题,React 引入分片处理机制,这就会出现在一次 rendering 过程中,不是所有的节点都是连续渲染完成的。
比如一次渲染需要 100ms,React 会将这次渲染分为 10 片,每次会渲染一片,当执行一片后,就会看一下有没有高优先的事情需要处理,如果有的话,就会交出控制权,停止渲染操作,先去响应该事件,从而避免页面”假死”。等该事件处理完成后,继续渲染。 这就会导致一些生命周期函数会被多次调用,引入 React Fiber 后对 React 生命周期钩子进行了调整。
虽然目前该模式为实验阶段,不过是 React 的未来之路。在最新的发布的 React 17 版本,其大部分更新跟该模式相关。所以该模式的正式推出只是时间问题。

目前的 Redux 和 mobx 是无法兼容 Concurrent Mode 的。这是因为在该模式下,渲染可以是随时触发的。在一个组件渲染一部分时,就被停止渲染,把执行权交出去,一段时间获取到执行权后,再从上次结束的地方继续渲染。这会造成什么问题呢?状态不一致。

Recoil 如何支持 Concurrent Mode

在 Recoil 的最新版本,已经提供了一些实验性的 api 来支持该模式。Recoil 在渲染时如果检测到状态已经发生了改变,则会重新渲染整个节点树来避免状态的不一致。目前该机制是高效的,之后会继续优化性能。

结论:

  • Redux是集中式管理state,而Recoil和Mobx都是分散式。
  • Redux和Mobx并不依赖于react环境,而Recoil只能在react环境中使用。
  • Recoil中状态的读写都是Hooks函数,目前没有提供类组件的使用方式。
  • Recoil是Facebook开发的,可以使用React内部的调度机制,这是Redux和Mobx不支持的。
  • Recoil目前还是实验阶段,想要应用到的自己的项目中,建议等待正式版。