React---Recoil

334 阅读2分钟

离散存储,不是集中式存储,水平方向,垂直方向

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 (选择器)衍生状态 ---以其他状态为参数的纯函数--类似计算属性

image.png

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个钩子:

image.png

const [useRecoilValue,useSetRecoilState] = useRecoilState()
const [count,useCount] = useState()

image.png

异步钩子

image.png

异步获取接口返回数据 image.png

image.png