离散存储,不是集中式存储,水平方向,垂直方向
Recoil 本身就是为了解决 React 全局数据流管理的问题,采用分散管理原子状态的设计模式。
Recoil 提出了一个新的状态管理单位 Atom,它是可更新和可订阅的,当一个 Atom 被更新时,每个被订阅的组件都会用新的值来重新渲染。如果从多个组件中使用同一个 Atom ,所有这些组件都会共享它们的状态。
改变一个 Atom 只会渲染特定的子组件,并不会让整个父组件重新渲染。
Redux、Mobx Redux 它本身虽然提供了强大的状态管理能力,但是使用的成本非常高,你还需要编写大量冗长的代码,另外像异步处理或缓存计算也不是这些库本身的能力,甚至需要借助其他的外部库。
基础使用
使用 recoil 状态的组件需要使用 RecoilRoot 包裹起来:
import {RecoilRoot} from 'recoil'
function App(){
return (
<RecoilRoot>
.......
</RecoilRoot>
)
}
定义状态 (atom | selector)
Atom (原子状态存储)是一种新的状态,但是和传统的 state 不同,它可以被任何组件订阅,当一个 Atom 被更新时,每个被订阅的组件都会用新的值来重新渲染。
selector (选择器)衍生状态 ---以其他状态为参数的纯函数--类似计算属性
export const nameState = atom({ key: 'nameState', default: 'ConardLi' });
不需要像 Redux 那样集中定义状态,可以像 Mobx 一样将数据分散定义在任何地方
创建一个 Atom,必须提供一个key ,其必须在RecoilRoot作用域中是唯一的,要提供一个默认值,默认值可以是一个静态值、函数甚至可以是一个异步函数。
使用
export const userInfoAtom = atom({
key: 'userInfoAtom',
default: {
usernmae: '张三',
score: 10
},
effects: [
({node,onSet}) => {
//设置数据时,监控 atom的变化
onSet((newValue: any,oldValue: any) => {
console.debug(``)
})
}
]
})
function UserInfo(){
const [userInfo, setUserInfo] = useRecoilState(userState.userInfo)
}
修改数据: 如果数据设置不可变,用 {produce} from 'immer'
const changeScore = ()
=> {
userInfo.score += 10;
setUserInfo({
...userInfo;
})
// Immutable 的写法
const newUserInfo = produce(userInfo,draft => {
draft.score += 10;
});
setUserInfo(newUserinfo)
}
订阅和更新状态
Recoil 采用 Hooks 方式订阅和更新状态,常用的是下面三个 APIuseRecoilState:
- 类似 useState 的一个 Hook,可以取到 atom 的值以及 setter 函数
- useSetRecoilState:只获取 setter 函数,如果只使用了这个函数,状态变化不会导致组件重新渲染
- useRecoilValue:只获取状态
(如果只要取一个值, 设置函数 就用 useSetRecoilvalue(),使用useRecoilvalue会导致重新渲染)
(同步)常用3个钩子:
const [useRecoilValue,useSetRecoilState] = useRecoilState()
const [count,useCount] = useState()
异步钩子
异步获取接口返回数据