为什么我停止使用 Redux 而改用 Recoil
Redux 有什么问题?
Redux 并不完美,但它是迄今为止 React 中最流行的状态管理库。让我们看看 Redux 有哪些不足之处:
-
巨大的学习曲线
有太多的概念需要学习,比如动作、动作创建器、reducers……当我们将基于类和函数的组件与使用 thunk 等的不同调度方式混合在一起时,它真的会吓到初学者 -
大量的样板
每次我们想要设置一个 redux 应用程序时,我们都必须创建 reducer、组合它们、创建一个存储、添加中间件、链接到 devtools、计算值等。我们需要添加许多具有自己配置的第三方库,并引入另一层复杂性。 -
重构文件夹结构
React 基于组件的方式与 Redux 的业务逻辑拆分方式不太契合。如果我们想将 Redux 引入到现有的 React 应用中,就需要更改文件结构,并且需要修改大量代码。
上下文 API
context API 并非真正的解决方案。它解决了 prop 钻取问题……而不是全局应用状态。你不能使用 context 在兄弟节点之间传递数据。子节点必须更新父节点,而父节点又会更新另一个子节点(兄弟节点)。
后坐力术语
与 redux 不同,我们需要理解很多概念……Recoil 中只有几个
原子
这是术语中最简单的部分...原子基本上是一种状态
选择器
根据另一个原子或选择器计算出的状态
畏缩
让我们从安装后坐力开始
npm i recoil
每当我们想要使用反冲时,我们都需要将RecoilRoot
组件放在组件树中的某个位置。
import React from 'react';
import {RecoilRoot} from 'root';
export default function App() {
return (
<RecoilRoot>
<h1>Recoil Demo</h1>
</RecoilRoot>
)
}
当我们想要创建一个时atom
,我们使用atom function
。
import React from 'react';
import { RecoilRoot, atom } from 'recoil';
const counter = atom({
key: "counter",
default: "0"
});
export default function App() {
return (
<RecoilRoot>
<h1>Recoil Demo</h1>
</RecoilRoot>
)
}
每个atom()
包含两个字段:
-
Key
关键是我们的原子名称。它在我们的应用程序中必须是唯一的,我们用它来获取原子的值。 -
Default
这default
是我们的原子的初始值
我们已经创建了一个原子,但我们还需要访问它。我们使用useRecoilState
钩子
import React from 'react';
import {RecoilRoot, useRecoilState, atom} from 'root';
const counter = atom({
key: "counter",
default: "0"
});
export default function App() {
const [number, setNumber] = useRecoilState(counter);
return (
<RecoilRoot>
<h1>Recoil Demo</h1>
<button onClick={() => setNumber(number + 1)}>{number}</button>
</RecoilRoot>
)
}
我们将counter
原子传递给。与React 中的钩子useRecoilState
非常相似,也返回状态的值和一个设置状态的函数。useState
useRecoilState
我添加了一个简单的按钮来显示 的值number
。当我们点击它时,我们会number
使用setNumber()
函数增加状态。
这个原子也可以在其他组件中使用。如果我们只想访问number
原子的值,可以使用useRecoilHook
。
function Display() {
const number = useRecoilValue(counter);
return <p>{number}</p>
}
派生状态
我们先来了解一下派生状态到底是什么。派生状态是基于另一个状态计算出来的状态。
在 recoil 中做到这一点非常容易。我们可以用selector()
函数。选择器是一个纯函数,它接受原子或其他选择器作为参数。我们将计数器的值立方。
const cubed = selector({
key: "cube",
get: ({ get }) => get(counter) ** 3
})
字段key
本身并不新鲜……它指定了我们状态的名称,正如我之前提到的,它必须始终是唯一的。字段get
才是事情变得有趣的地方。我同意它的语法很复杂,但它赋予了我们强大的功能,并扩展了可能性。每当选择器使用的原子发生变化时,选择器就会重新计算。让我们逐行看一下代码。
我们为该字段赋予一个函数get
。Recoil 将一个对象传入该函数,并从该对象解构该get
字段。该get
字段是一个函数,允许传入key
原子或选择器的 并访问其值。然后,我们对其进行 次幂运算3
。这里我们只使用了一个原子atom
,但我们可以使用多个原子进行计算。
import {selector} from 'recoil';
const cubed = selector({
key: "totalPrice",
get: ({ get }) => {
get(numState) ** 3
}
})
文件夹结构
假设我们的应用中有两大类状态:用户和待办事项。所有原子都放进去/atoms
,选择器也放进去/selectors
。与用户相关的原子会放进去/atoms/users.js
,与待办事项相关的原子会放进去,/atoms/todos.js
以此类推。
就到这里,感谢大家阅读到这里。希望大家喜欢这篇文章,如果喜欢的话,请点赞并关注我。再见👋
文章来源:https://dev.to/akashshyam/why-i-stopped-using-redux-and-used-recoil-instead-e6a