概述
Recoil的简单实践和思考
背景
随着react18的发布,和react官方新文档正在逐步完善。有兴趣的小伙伴可以去react新文档的仓库issues里面查找有关于class组件的提问和回答。
其中有一条提问是:“所以,类组件会被废除吗?”。
官方回答的大意是:“未来的react新文档全面以hooks为主,至于类组件很有可能会变成一个独立的包来维护”。
(详细问答在github.com/reactjs/rea…)
很明显,就是hooks的时代正式官宣。
动机
最近项目中全部使用函数组件+hooks,有一个常见的问题,想要管理一些全局状态,想找一个完美与hooks相对应的状态管理库。redux繁琐的写法个人看来与函数组件显得格格不入,集中式管理略显笨重。市面上太多各种剖析redux各种原理的热点文章,其实倒不是刻意与众不同,也不是独辟蹊径。每个人每个项目都有适合的状态管理工具。在项目技术选型中,不是人云亦云,而是自己了解项目特点,调研相关的利害关系,最后找到最适合自己项目的工具。因为吧,写出代码交付是为了赚钱;写,也得尽可能要求自己用优雅的代码赚钱~这对于自己的和公司是一种双赢的关系。血赚不亏。
我当时目的有三个:
- 项目不算特别大型,关于全局状态管理,尽可能越简单越好。
- 厌倦了redux的繁琐写法,想找一个纯hooks的全局状态管理工具。
- 当时出了几个开源事故新闻,尽可能官方维护稳妥一点。
然后,上网冲浪了一段时间,最后看到了recoil。
- 简单: 会用useState就会用recoil,上手成本极低。(顶多再来点异步和suspense)
- 写法: 就是useState写法,ahooks用过吧,设计传参方式差不多,似曾相识的感觉。
- 缘分:react是Facebook开源的吧,recoil不是react团队,但是来自于Facebook团队啊!同一个妈生的,稳。
下面就是一个最简的实践案例:
不会仔细写atom,selector和怎么包裹外层组件,官网文档写的描述非常清晰。养成看官方文档的习惯~
recoil实现后台用户信息的获取和更新
需求
用户信息有关的组件一般位于相对来说最外层的组件之中,我希望改变了用户id之后自动发送请求得到最新的用户名并渲染。
get start
定义一个atom
, 你可以想象成 useState 的初始值。因为是全局的“useState“,你怎么知道它是不是唯一的,是吧,习惯性思考肯定有个唯一标识符,作为它的id之类的。
atom.js
import { atom } from "recoil";
export const userID = atom({
key: "ID", // 唯一标识符
default: 1,// 初始值
});
初始值定义好了,当然初始值肯定有对应的方法。怎么自动根据我这个可以变化的id自动请求呢?
”根据这个id“–>“多半是作为依赖”
“根据id自动发送请求”–>”多半是此依赖会在一个封装好异步函数里面“
selector.js
import { getUserName } from "@/api/request"; // 请求
import { selector } from "recoil";
import { userID } from "./atom";
export const userName = selector({
key: "NAME",
get: async ({ get }) => {
return await getUserName(get(userID)); // 一个异步的selector
},
});
当然这个selector
可以类比成一个异步返回的 useState 的值。
有了异步的值,自然而然就要考虑到,js里面想要拿到这个值,要么就是promise全家桶处理方式,要么就是有专门获取这种异步值的方法。
翻了翻官方文档,他们也讲了这个类似的案例。
以下是作为渲染和怎么使用atom
和selector
以及他们的关系:
User.jsx
// ...
const user_name = useRecoilValueLoadable(userName);
let username = ""; // 想要渲染
switch (user_name.state) {
case "hasValue":
username = user_name.contents.data.username;
break;
case "loading":
username = "";
break;
case "hasError":
throw user_name.contents;
default:
}
// ...
/*
useRecoilValueLoadable这个钩子传入一个异步的selector,内部自己处理,
返回一个对象,根据时序异步状态的变化,会产生三个不同时刻对应的对象
{state:"loading",contents:Promise}
{state:"hasValue",contents:请求成功的res}
{state:"hasError",contents:错误信息相关}
*/
return <组件 username={username} >
这是异步的获取,需要搭配suspense
组件
<Suspense fallback={<Loading />}>
<User />
</Suspense>
最后是改变id:
const [, setUserID] = useRecoilState(userID); // usestate的用法操作atom
// ...
<Button
onClick={() => {
setUserID(Math.random(1, 100));
}}>
更换userID
</Button>
// ...
需要的思考方式:
- useState使用方法举一反三的类比思考
- js异步操作以及async/await的使用
- Promise的状态
- react中的异步加载组件Suspense
几乎没有什么特别的需要注意的点,recoil还提供的很多api,不过实际使用,就那个几个常用。
像极了react,你会用useState和useEffect就能上手开发。(o)
最后
以上就是懵懂发卡为你收集整理的Recoil的简单实践和思考Recoil的简单实践和思考的全部内容,希望文章能够帮你解决Recoil的简单实践和思考Recoil的简单实践和思考所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复