如果你的 React 应用中准备/刚好用到 MobX + SWR, 又刚好遇到下面的问题:
- 共享 MobX 前端状态,要不断重复写模版代码
- 想共享 SWR 拉取的状态和数据结果,要不断的组装同一个请求参数,或者要为这些需要共享的后端数据添加新的 store 实例
Spreado 或许是一个不错的选择,这些工作都可以简化为一个 hook 或一个 get/set 方法。
阅读 Spreado - 轻松地在 React 组件间传播状态和数据 初步了解下 Sperado 之后,我们会发现 Spreado 仅仅是对目前主流的状态管理库和数据拉取库的易用封装,帮助你少写重复代码的同时,解决一些工作中遇到的痛点。
核心 API
useSpreadOut/setSpreadOut– React 组件存储对象到 Spreado 中useSpreadIn/getSpreadIn– React 组件获取 Spreado 中的对象
安装
NPM: npm install --save spreado
Yarn: yarn add spreado
初始化
只需要如下简单的初始化,不需要去定义 MobX 用于存储状态的 store,这些工作都交给 Spreado。
虽然 MobX 基本上无样版代码风格,但 Spreado 可以让你更省心。
import React, {FC} from 'react';
import {SpreadoSetupProvider} from 'spreado';
import {SpreadoSetupForMobXSwr} from 'spreado/for-mobx-swr';
import {SWRConfig} from 'swr';
const spreadoSetup = new SpreadoSetupForMobXSwr();
const App: FC = () => {
return (
<SpreadoSetupProvider setup={spreadoSetup}>
<div>...</div>
</SpreadoSetupProvider>
);
};
document.body.clientWidth;
}
共享一个前端状态
无需关心 MobX 中一些约束,比如需要为组件添加 observer 包裹。
同样这些逻辑都交给 Spreado,存储或者更新状态你只需要使用 setSpreadOut ,获取状态使用你只需要使用 useSpreadIn/getSpreadoIn (根据使用场景选择)。
import {setSpreadOut, useSpreadIn} from 'spreado';
const INDEX_OF_COUNT = 'INDEX_OF_COUNT';
function useCount() {
return useSpreadIn<number>(INDEX_OF_COUNT, 0);
}
function setCount(v: number) {
return setSpreadOut(INDEX_OF_COUNT, v);
}
function getCount() {
return getSpreadIn(INDEX_OF_COUNT);
}
const ComponentA: FC = () => {
const count = useCounter();
return (
<div>
<div>{count}</div>
<button onClick={() => setCount(count+1)}>INCREMENT</button>
<button onClick={() => setCount(count-1)}>DECREMENT</button>
</div>
);
};
const ComponentB: FC = () => {
const count = useCounter();
const onClickGetCountButton = () => {
const count = getCount()
// ...
}
return (
<div>
{count === 6 && <div>ComponentB logic related to count</div>}
<button onClick={onClickGetCountButton}>Get Count</button>
</div>
);
};
共享 SWR 拉取结果
你会不会遇到这样的困扰,在 component A 中使用 useSWR 发起请求 R1,但在 component B 需要共享 R1 的 isLoading, isSuccess 状态,component C 中需要共享 R1 的 data. 两种可能的解决办法是:
- 重新调用 useSWR(R1),但发现请求用到的参数 component B 和 component C 都有残缺,或者压根没有,你可能会通过 props,或者存储到一个全局的位置,目的就是组装这个参数
- 将 useSWR 的返回,包括 isLoading, isSuccess,data 等等全部存储到 store,这时你不得不去定义一个 store 实例对象。
但是当你有了 Spreado, 你会发现一切变的那么简单,只需要用到这样两个 hook 就可以解决问题。
import useSWR from "swr";
import {useSpreadIn, useSpreadOut} from 'spreado';
const INDEX_OF_FROM_SWR_DATA = 'INDEX_OF_FROM_SWR_DATA';
function useFromSWRDataQuerySpreadOut(params: ParamsForBEDataQuery) {
return useSpreadOut(
INDEX_OF_FROM_SWR_DATA,
useSWR([INDEX_OF_FROM_SWR_DATA, params], () => fetch(params))
);
}
function useFromSWRDataQueryQuerySpreadIn() {
return useSpreadIn<ReturnType<typeof useFromSWRDataQuerySpreadOut>>(INDEX_OF_FROM_SWR_DATA, {});
}
const ComponentA: FC = () => {
const params = from_a_form_data();
const {isLoading, isSuccess, data, refetch} = useFromSWRDataQuerySpreadOut(params);
return (
<>
{isLoading && <Loading />}
{isSuccess && <ResultA data={data} />}
<button onClick={() => refetch()}>Refresh data</button>
</>
);
};
const ComponentB: FC = () => {
const {isLoading, isSuccess} = useFromSWRDataQueryQuerySpreadIn();
return (
<>
{isLoading && <Loading />}
{isSuccess && <div>ComponentB logic</div>}
</>
);
};
const ComponentC: FC = () => {
const {data} = useFromSWRDataQueryQuerySpreadIn();
return (
<>
{data && <div>ComponentC logic</div>}
</>
);
};
到这里关于 Spreado 集成 MobX 和 SWR 基本上就说完了,总的来说,有了 Spreado 可以让 MobX、SWR 等这些状态管理库和数据拉取库在结合起来时更加易用,帮助你解决一些重复要写的逻辑,让你只关注存和取就可以,还不错吧 ~
写在最后
不知道 spreado 是否击中了你的内心,希望它可以帮助到你。如果有任何的疑问或想法,欢迎在 spreado/issues 留言,中英文都可以。如果有时间和兴趣,欢迎直接提交代码,具体可以参考开发引导。如果觉得小工具有帮助,请给 GitHub repo react-easier/spreado 点个 ⭐️,这也是我们不断前行的动力 😃。