说到状态管理器,轮子满天飞。在 Class 时代,redux 与 mobx 几乎占据了全部市场,几乎没有没用过 redux 的同学。随着 Hooks 的诞生,新的一批轮子应运而生,其中有代表性的有 unstated-next、constate 等等。
当然无论什么轮子,要解决的问题都是一样的:跨组件状态共享。在解决这个核心问题的同时,需要尽可能的满足以下几个特性:

  • TypeScript 支持

  • 友好的异步支持

  • 支持状态互相依赖

  • 同时支持 Class 与 Hooks 组件

  • 使用简单

Recoil 体验

最近,facebook 官方出了一个状态管理器解决方案 Recoil[1],我们来体验一下。

准备工作

使用 Recoil,我们需要在项目最外层包一个 RecoilRoot ,这个和大部分状态管理器一致,通过 context 来跨组件传递数据。

import React from 'react';
import { RecoilRoot } from 'recoil';function App() {return (<RecoilRoot>...</RecoilRoot>);
}

跨组件状态共享

状态最简单的就是定义和使用。在 Recoil 中,通过 atom 来定义一个状态。

const inputValueState = atom({key: "inputValue",default: ""
});

如上面的代码所示,我们定义了一个 inputValue 状态,它的默认值是空字符串。
需要注意的是 key 字段,它应该是全局唯一的。这个 key 主要为了 debug 方便,持久化数据(数据恢复时的唯一标识),以及可以方便的看到全局 atoms 树。

消费状态也比较简单,通过 useRecoilState 来消费状态。

import React from "react";
import { useRecoilState } from "recoil";
import { inputValue } from "../store";const InputA = () => {const [value, setValue] = useRecoilState(inputValueState);return <input value={value} onChange={e => setValue(e.target.value)} />;
};export default InputA;

是不是很简单?Recoil 的基础用法就是这样的。我在这里写了一个 demo[2],你可以体验下。

状态互相依赖

有些状态需要依赖其它状态,这时候就要用 selector 来定义这个状态了。
比如,我们需要定义一个新的状态 filterdInputValue ,它是过滤 inputValue 中的数字后的值。

const filterdInputValue = selector({key: "filterdInputValue",get: ({get}) => {// 通过 get 可以读取其它状态const inputValue = get(inputValueState);return inputValue.replace(/[0-9]/ig, "");},
});

selector 比较简单,就是为了实现状态的依赖。你可以在这个 demo[3] 体验下。

异步支持

良好的异步请求支持是状态管理器必不可少的。Recoil 提供了一个 useRecoilValueLoadable 来处理异步请求。直接上例子:

const currentUserNameQuery = selector({key: "CurrentUserName",get: async () => {const response = await queryUserInfo();return response.name;}
});

我们需要通过 selector 来定义异步状态,如果 get 函数是一个 Promise,则代表该状态为异步状态,需要使用 useRecoilValueLoadable 来消费该状态。

const UserName = () => {const userNameLoadable = useRecoilValueLoadable(currentUserNameQuery);switch (userNameLoadable.state) {case "hasValue":return <div>{userNameLoadable.contents}</div>;case "loading":return <div>Loading...</div>;case "hasError":throw userNameLoadable.contents;}
};

从上面例子可以看到, useRecoilValueLoadable 返回的状态,可以通过 state 字段读取到异步请求的状态。我写了个 demo[4],你可以体验下。

当然通过 useRecoilValueLoadable 来消费异步状态,比较符合我们当前的习惯。但 Recoil 更推荐通过 React.Suspense 来消费异步状态,这里就仁者见仁了,虽然 Suspense 可能是方向,但用起来是还不太习惯。

const UserName = () => {const userName = useRecoilValue(currentUserNameQuery);return <>{userName}</>}
};
function MyApp() {return (<React.Suspense fallback={<div>Loading...</div>}><UserName /></React.Suspense>);
}

评价

优点

  • 之前状态管理器满天飞,如果官方能一统天下,应该算一件好事情。

  • 对 React concurrent 模式支持良好。

不足

当前 Recoil 还处于开发阶段,文档都还不是很全。基于现状,说几点我的感受。

1. 没有使用 ts 实现,目前不支持 ts

这点我很惊讶,也是写这个文章的时候才发现的,很奇怪。讲道理 Recoil 支持 typescript 应该是顺手的事情,可能后期需要来个 @types/recoil 吧。

2. 目前没有支持 Class 组件消费状态。

这个特性应该是必备的,应该不会彻底抛弃 Class 组件。估计下个版本肯定会支持的这个特性的。实现成本较低,不支持的话就太反人类了。

3. API 偏多,有一定上手成本。


各类 API 一共有 19 个,偏复杂了。感觉很多都是可以合并的,比如 atom 和 selector 合并成一个等等(也可能是我考虑不成熟)。建议官方可以考虑精简精简,本来是一个很简单的东西,搞的太复杂了。

4. 消费较繁琐

我们需要消费一个状态的时候,需要 import 两个东西,比较繁琐。

import { useRecoilState } from "recoil";
import { inputValueState } from "../store";// 用法
useRecoilState(inputValueState);

本来应该可以直接通过字符串 key 消费的,但这样和 redux 问题一样了,无法支持 ts。

import { useRecoilState } from "recoil";useRecoilState('inputValueState');

无论如果,import 两个东西不是一个好的用法。

5. 没有足够的亮点

没有看到让人眼前一亮的东西,没有使用冲动。静观发展~

后记

Recoil 整体看下来,比较中庸,需要静观发展。
另外推荐一下我目前正在用的最简单的 React 状态管理器 hox[5],只有一个 API,非常符合直觉,没有任何上手成本,完全拥抱 Hooks ????。

Reference

[1]

Recoil: https://recoiljs.org/

[2]

demo: https://codesandbox.io/s/recoil-input-demo-7vly9?file=/src/components/InputA.js

[3]

demo: https://codesandbox.io/s/recoil-selector-demo-sn2kw?file=/src/App.js

[4]

demo: https://codesandbox.io/s/recoil-async-demo-qu6vw?file=/src/App.js

[5]

hox: https://github.com/umijs/hox

◆ ◆ ◆  ◆ ◆

学习交流

  • 关注公众号【前端宇宙】,每日获取好文推荐

  • 添加微信,入群交流

“在看和转发”就是最大的支持

Recoil - Facebook 官方 React 状态管理器相关推荐

  1. [react] 状态管理器它精髓是什么?

    [react] 状态管理器它精髓是什么? 统一的数据管理 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

  2. [react] 状态管理器解决了什么问题?什么时候用状态管理器?

    [react] 状态管理器解决了什么问题?什么时候用状态管理器? 专注 view 层 React 官网是这么简介的.JavaScript library for building user inter ...

  3. hooks组件封装 react_名符其实的react下一代状态管理器hox

    自从 React16 版本发布 Hooks 以来,大家纷纷上车尝鲜.毫无疑问, Hooks 在一定程度上解决了组件间功能和逻辑复用的问题,在组件间的逻辑的封装和复用确实真香,但 Hooks 在数据状态 ...

  4. 名符其实的react下一代状态管理器hox

    前言 自从React16版本发布Hooks以来,大家纷纷上车尝鲜.毫无疑问,Hooks在一定程度上解决了组件间功能和逻辑复用的问题,在组件间的逻辑的封装和复用确实真香,但Hooks在数据状态的共享方法 ...

  5. [react] 什么时候使用状态管理器?

    [react] 什么时候使用状态管理器? 1用户的使用方式复杂 2.不同身份的用户有不同的使用方式(比如普通用户和管理员) 3.多个用户之间可以协作 4.与服务器大量交互,或者使用了WebSocket ...

  6. flux react php,Vue的Flux框架之Vuex状态管理器

    学习vue之前,最重要是弄懂两个概念,一是"what",要理解vuex是什么:二是"why",要清楚为什么要用vuex. Vuex是什么? Vuex 类似 Re ...

  7. [译] ⚛ React 状态管理工具博物馆

    原文地址:⚛ The React State Museum: ⚡️View the hottest state management libs for React 原文作者:Gant Laborde ...

  8. 选择正确的 React 状态管理解决方案的指南

    编者注 :本文于 2022 年 9 月 23 日更新,添加了关于为什么我们需要在 React 中进行状态管理的信息,添加了之前未包含在文章中的其他状态管理工具,例如 Jotai.MobX 和 Zusa ...

  9. [必须要了解的React状态管理]阅读hox对状态管理的思考

    对于react 状态管理已经是老生畅谈的话题,官方没有给出最佳实践因此市面上关于状态管理的探索从未停止过. 知识有限,如有不对请留言或私信 感激ing.欢迎交流

  10. Vue的状态管理器:Vuex

    无需原生开发基础,也能完美呈现京东商城.<混合开发京东商城系统,提前布局大前端>课程融合vue.Android.IOS等目前流行的前端和移动端技术,混合开发经典电商APP--京东.课程将各 ...

最新文章

  1. CTF-不一样的凯撒密码
  2. AutoCAD VBA对齐对象
  3. Java float类型怎么把小数位数限制为2位
  4. xlswriter-用于Excel 2007+XLSX文件中读取数据
  5. 运动会成绩管理系统python_基于Eclipse+Mysql+Tomcat+MVC开发得大学运动会管理系统
  6. 一汽大众汽车宣布召回19.1万辆国产奥迪A6L
  7. js判断ipad还是安卓_最近iPad做电子笔记很流行?综合分析你知道的所有笔记方式。...
  8. IFC2x3标准阅读
  9. smart client auto update
  10. liunx 常用操作
  11. 关于离散数学的一点事情
  12. 【每日算法Day 66】经典面试题:不用四则运算如何做加法?
  13. Dubbo介绍前篇------单一应用框架、垂直应用框架、分布式应用框架、流动计算框架,及RPC的简介
  14. SPF算法简单解析过程
  15. DynDNS免费动态域名解析
  16. 什么是Cisco ACI?
  17. Java SE第10章 异常处理
  18. java程序员秃顶,【本人秃顶程序员】使用Azure Function + Cognitive Services 实现图片自动化审核...
  19. 读《格鲁夫给经理人的第一课》
  20. 基于 FCCA 的多特征融合的检索方法

热门文章

  1. 3A之自动白平衡(AWB)篇
  2. 使用wxpy实现在微信定时发送文件和消息
  3. pdf 添加水印、页眉页脚、签名
  4. python游走代码_用Python模拟随机游走(Random walks)
  5. Solidity简单例子-代理投票
  6. Exception evaluating SpringEL expression异常处理
  7. mysql mtq_mysql实现远程登录
  8. Linux文件管理之(高级)、⽂件查找、上传与下载、输出与重定向、字符处理命令、打包压缩解压缩、文件系统
  9. 高绩效团队-VUCA时代的五个管理策略《三》—创新管理
  10. Excel VBA单元格数据自增1