Recoil 最佳实践

Recoil 是 React 官方 meta (facebook) 官方实验室的状态管理库,贴合 React hooks,自由度很高,所以要在项目中做一些规范,以便提供最佳的实践。

官方文档有对核心概念的解释,但是,这里主要以我个人的理解去诠释这些核心概念。

atom 是 Recoil 的核心概念,在项目中,主要将它用来初始化一个状态。那如何处理这个状态呢,selectorFamily 就像一面镜子,它可以折射 atom 的状态给组件(当然,这里最好就是直接从atom读取状态),也可以将组件想要改变的状态意图通过它来折射给 atom。

最佳目录结构

/pages/index.tsx

/components/plus.component.tsx
/components/minus.component.tsx
/components/reset.component.tsx

/recoil/count.recoil.ts

Recoil

/recoil/count.recoil.ts

import {
    atom,
    DefaultValue,
    selectorFamily,
} from 'recoil';

const count = atom({
    key: 'count',
    default: 0
});

const changeCount = selectorFamily({
    key: 'changeCount',
    get: () => ({ get }) => { return get(count) },
    set: (params) => ({ set }, newValue: any) => {
        switch (params) {
            case '+':
                set(
                    count,
                    newValue instanceof DefaultValue ? newValue : (newValue + 1)
                );
                break;
            case '-':
                if (newValue >= 1) {
                    set(
                        count,
                        newValue instanceof DefaultValue ? newValue : (newValue - 1)
                    )
                };
                break;
            default: set(
                count,
                newValue
            );
        };
    }
});

export { count, changeCount };

/pages/index.tsx

import Plus from '../components/plus.component';
import Minus from '../components/minus.component';
import CountReset from '../components/countReset.component';
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil';
import { changeCount, count } from '../recoil/count.recoil';

const value = useRecoilValue(count);

const [plusCount, setPlusCount] = useRecoilState(changeCount('+'));
const plusFunc = () => setPlusCount(plusCount);

const [minusCount, setMinusCount] = useRecoilState(changeCount('-'));
const minusFunc = () => setMinusCount(minusCount);

const resetFunc = useResetRecoilState(changeCount(''));

<h1>{value}</h1>
<Plus plusFunc={plusFunc} />
<Minus minusFunc={minusFunc} />
<CountReset resetFunc={resetFunc} />

/components/plus.component.tsx

export default function (props:any) {
    return (
        <button onClick={props.plusFunc}>+</button>
    )
}

/component/minus.component.tsx

export default function (props:any) {
    return (
        <button onClick={props.minusFunc}>-</button>
    )
}

/components/resetCount.tsx

export default function (props:any) {
    return (
        <button onClick={props.resetFunc}>reset</button>
    )
}