热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RecoilFacebook官方React状态管理器

Recoil-Facebook官方React状态管理器,Go语言社区,Golang程序员人脉社


说到状态管理器,轮子满天飞。在 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 (
    
        ...
    

  );
}

跨组件状态共享


状态最简单的就是定义和使用。在 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  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 

{userNameLoadable.contents}
;
    case "loading":
      return 
Loading...
;
    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 (
    Loading...

}>
      
    
  );
}

评价


优点


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

  • 对 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


◆ ◆ ◆  ◆ ◆


学习交流


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

  • 添加微信,入群交流



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





推荐阅读
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
  • 详解react组件通讯方式(多种)
    这篇文章主要介绍了详解react组件通讯方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着 ... [详细]
  • ReactJSUIAnt设计空组件原文:https://w ... [详细]
  • Vue3 拥抱 TypeScript 的完整项目结构搭建
    大厂技术高级前端Node进阶点击上方程序员成长指北,关注公众号回复1,加入高级Node交流群一个完整的Vue3Ts项目,支持.vue和.tsx写法项目地 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 本文介绍了如何使用elementui分页组件进行分页功能的改写,只需一行代码即可调用。通过封装分页组件,避免在每个页面都写跳转请求的重复代码。详细的代码示例和使用方法在正文中给出。 ... [详细]
  • node.jsrequire和ES6导入导出的区别原 ... [详细]
  • Vue3中setup函数的参数props和context配置详解
    本文详细介绍了Vue3中setup函数的参数props和context的配置方法,包括props的接收和配置声明,以及未通过props进行接收配置时的输出值。同时还介绍了父组件传递给子组件的值和模板的相关内容。阅读本文后,读者将对Vue3中setup函数的参数props和context的配置有更深入的理解。 ... [详细]
  • 本文介绍了自学Vue的第01天的内容,包括学习目标、学习资料的收集和学习方法的选择。作者解释了为什么要学习Vue以及选择Vue的原因,包括完善的中文文档、较低的学习曲线、使用人数众多等。作者还列举了自己选择的学习资料,包括全新vue2.5核心技术全方位讲解+实战精讲教程、全新vue2.5项目实战全家桶单页面仿京东电商等。最后,作者提出了学习方法,包括简单的入门课程和实战课程。 ... [详细]
  • 在加载一个第三方厂商的dll文件时,提示“找不到指定模块,加载失败”。由于缺乏必要的技术支持,百思不得期间。后来发现一个有用的工具 ... [详细]
  • 我正在尝试使用scrapycrallsingle运行完美运行的scrapy蜘蛛,但我无法在python脚本中运行它.主要问题是从不执行SingleBlogSpider.parse方 ... [详细]
  • React提供三种方式创建Refs:字符串Refs(将被废弃)回调函数RefsReact.createRef(从React16.3开始)第一种方式不推荐使用,原因在此,并且可能会在之后的版本移除。classMyComponentextendsReact.Component{constructor(props){sup ... [详细]
author-avatar
mobiledu2502885385
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有