动机

出于兼容性和简单的原因,最好使用React内置的状态管理功能,而不是外部的全局状态。但是React有一定的局限性:

  • 组件的状态只能通过推送到共同祖先来共享,但这可能包括一个巨大的树,然后需要重新渲染。
  • Context只能存储一个单一的值,而不是一个不确定的值集,每个值都有自己的消费者。
  • 这两点使得我们很难将树的顶部(状态必须住的地方)与树的叶子(状态使用的地方)进行代码分割。

我们希望在保持API和语义和行为尽可能的接近React的同时,又能改进以上问题。

Recoil 定义了一个有向图,它与 React 树正交,但也是内在附着在 React 树上。状态变化从这个图的根部(我们称之为atom)通过纯函数(我们称之为selector)流向组件。原理如下:

  • 我们得到了一个无样板代码的API,其中共享状态具有和React本地状态一样简单的get/set接口(如果需要的话,还可以用Reducer等进行封装)。
  • 我们有可能与Concurrent模式和其他新的React功能兼容,让它们变得具有可用性。
  • 状态的定义是增量和分布式的,使得代码的拆分成为可能。
  • 状态可以用派生数据替换,而无需修改使用它的组件。
  • 派生数据可以在同步和异步之间移动,而无需修改使用它的组件。
  • 我们可以把导航作为一个一等概念来对待,甚至可以对链接中的状态转换进行编码。
  • 以一种向后兼容的方式持久化整个应用状态是很容易的,所以持久化的状态可以在应用的变更中保存下来。

概览

使用Recoil可以创建一个数据流的图,它从Atom(共享状态)通过Selector(纯函数)流到你的 React 组件。Atom是组件可以订阅的状态单位。Selector可以同步或异步转换这个状态。

Atoms

Atom是状态的单位。它们是可更新和可订阅的:当一个Atom被更新时,每个被订阅的组件都会用新的值来重新渲染。它们也可以在运行时创建。Atom可以用来代替 React 本地组件状态。如果从多个组件中使用同一个Atom,所有这些组件都会共享它们的状态。

Atom是使用atom函数创建的:

const fontSizeState = atom({key: 'fontSizeState',default: 14,
});

Atom需要一个唯一的key,这个key用于调试、持久化,以及某些高级的API,让你看到所有Atom的图。两个Atom有相同的key是一个错误,所以要确保它们是全局唯一的。和 React 组件状态一样,它们也有一个默认值。

要从组件中读取和写入Atom,我们使用一个名为useRecoilState的钩子。它就像React的useState一样,但现在组件之间可以共享状态:

function FontButton() {const [fontSize, setFontSize] = useRecoilState(fontSizeState);return (<button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>Click to Enlarge</button>);
}

点击该按钮会把按钮的字体大小增加一个字号。但现在一些其他组件也可以使用同样的字体大小。

Selectors

Selectors是一个纯函数,它接受Atom或其他Selectors作为输入。当这些上游的Atom或Selectors被更新时,Selectors函数将被重新评估。组件可以像Atom一样订阅Selectors,当Selectors发生变化时,组件就会被重新渲染。

Selectors用于计算基于状态的派生数据。这让我们可以避免冗余状态,通常不需要reducers来保持状态的同步和有效。相反,一个最小的状态集被存储在Atom中,而其他的一切都作为该最小状态的函数有效计算。由于Selectors可以跟踪哪些组件需要它们,以及它们依赖哪些状态,因此它们使这种功能方法更加高效。

从组件的角度来看,Selectors和Atom具有相同的接口,因此可以相互替代。

Selectors是用selector函数来定义的:

const fontSizeLabelState = selector({key: 'fontSizeLabelState',get: ({get}) => {const fontSize = get(fontSizeState);const unit = 'px';return `${fontSize}${unit}`;},
});

get属性是要计算的函数。它可以使用传递给它的get参数访问Atom和其他Selectors的值。每当它访问另一个Atom或Selectors时,就会创建一个依赖关系,这样更新另一个Atom或Selectors就会导致这个Atom或Selectors被重新计算。

在这个fontSizeLabelState示例中,Selectors有一个依赖关系:fontSizeStateAtom。从概念上讲,fontSizeLabelStateSelectors的行为就像一个纯函数,它以fontSizeState作为输入,并返回一个格式化的字体大小标签作为输出。

Selectors可以使用useRecoilValue()来读取,它取一个Atom或Selectors作为参数并返回相应的值。我们不使用useRecoilState(),因为fontSizeLabelStateSelectors是不可写的(关于可写Selectors的更多信息,请参阅SelectorsAPI参考):

function FontButton() {const [fontSize, setFontSize] = useRecoilState(fontSizeState);const fontSizeLabel = useRecoilValue(fontSizeLabelState);return (<><div>Current font size: ${fontSizeLabel}</div><button onClick={() => setFontSize(fontSize + 1)} style={{fontSize}}>Click to Enlarge</button></>);
}

现在点击该按钮会触发两件事:它可以增加按钮的字体大小,同时还可以更新字体大小标签以反映当前的字体大小。

以上就是Recoil官方文档的部分简介。

想了解更多信息请查阅官方网站:https://recoiljs.org/

react全局状态管理_Recoil - Facebook出品的全新React状态管理库相关推荐

  1. react怎么存上一页_如何实现 React 中的状态自动保存?

    什么是状态保存? 假设有下述场景: 移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个位置,用户看到了感兴趣的项目, ...

  2. react全局方法_前端面试题 ---react

    高阶组件相关 什么是高阶组件,它有哪些运用? 高阶组件就是一个函数,接收一个组件,经过处理后返回后的新的组件: 高阶组件,不是真正意义上的组件,其实是一种模式: 可以对逻辑代码进行抽离,或者添加某个共 ...

  3. P22-Vue3后台管理系统-权限管理之路由守卫判断⽤户登录状态

    P22-Vue3后台管理系统-权限管理之路由守卫判断⽤户登录状态 文章目录 P22-Vue3后台管理系统-权限管理之路由守卫判断⽤户登录状态 1.概述 2.mock接口返回token 2.1.mock ...

  4. HTTP 协议入门 — (TCP/IP协议族、通信传输流、URI 与 URL 的区别、Cookie 状态管理、HTTP 支持的方法、状态码类别、HTTP 首部字段)

    TCP/IP协议族 在介绍 HTTP 协议之前,我们先对 TCP/IP 协议族有个大概的了解,TCP/IP 协议从上到下主要分为应用层.传输层.网络层和数据链路层,各层的主要功能如下表所示: 协议层 ...

  5. Facebook 正在大规模重构 React Native

    web前端教程 用大白话,来讲编程 Facebook 五年前为 React Native 框架设计的原则,影响了与 JavaScript 代码的整合程度,也加大了某些特性的开发难度. 因此 Faceb ...

  6. Facebook妥协了,React回归

    一大早上睡醒在网上看到消息说,React专利条款事件反转了,Facebook作出让步,在下周重新发布新的专利许可证,把许可证改为标准的MIT协议. 可见Facebook当初发布专利条款后,没有料到社区 ...

  7. android 布局dock,Android电源管理专题之获取和监测Dock状态和类型

    Android电源管理专题之获取和监测Dock状态和类型 (2013-04-07 16:36:00) 标签: android 电源管理 dock it Android 设备可以接在不同类型的 Dock ...

  8. react 哲学_细聊Concent amp; Recoil , 探索react数据流的新开发模式

    开源不易,感谢你的支持,❤ star me if you like concent ^_^ 序言 之前发表了一篇文章 redux.mobx.concent特性大比拼, 看后生如何对局前辈,吸引了不少感 ...

  9. react在线文件_编程界“滥竽充数者”?React是否名不副实?

    全文共 3672字,预计学习时长 11分钟 图源:Aphinya Dechalert提供 年初,笔者试着真正使用了一回React库.由于对Angular有一定的了解,笔者对库中提出的概念保持开放包容的 ...

  10. react生命周期函数_如何优雅的消灭掉react生命周期函数

    开源不易,感谢你的支持,❤ star concent^_^ 序言 在react应用里,存在一个顶层组件,该组件的生命周期很长,除了人为的调用unmountComponentAtNode接口来卸载掉它和 ...

最新文章

  1. PDO的bindParam与bindValue的区别
  2. varnish Cconfigure
  3. boost之对象池使用实例
  4. python if elif else_python:通讯录(字典+while+if/else)
  5. 《Python Cookbook 3rd》笔记(2.4):字符串匹配和搜索
  6. linux大数据命令操作
  7. C#中将原表复制到新表
  8. Linux如何产看系统信息
  9. python+php+变量传递,将变量从php传递给python,将python传递给php
  10. iOS APP安全杂谈
  11. matlab绘制三角函数乘除法的问题
  12. 移动前端开发和web前端开发的区别?
  13. [python爬虫] Selenium爬取新浪微博内容及用户信息
  14. 网站设计的好坏对宣传的效果的影响!
  15. Android指纹支付 - android M / P 全适配
  16. PA2.2 PA2.3
  17. 我在周日凌晨执意顶着困意喝酒
  18. Zain Iraq通过MATRIXX Software推出突破性数字品牌oodi
  19. oracle 在plsql中创建procedure并调用
  20. 人生重开模拟器突然火爆 GitHub,赶紧来玩一玩

热门文章

  1. BurpSuite使用详解(三)Spider功能
  2. 基于随机游走的PersonalRank
  3. Urchin再包装 Google提供免费网络流量分析工具(zz)
  4. Python 数据分析之 Numpy (三)
  5. BUUCTF [0CTF 2016] piapiapia
  6. 2018-2019 2 20165203 《网络对抗技术》 Exp4 恶意代码分析
  7. zz红外焦平面阵列用信号处理电路
  8. 【精美前端模板】你还不心动吗?
  9. android 限制后台进程,Android O Preview 相关-后台执行限制
  10. xxl-job定时任务