Spreado - 基于 MobX + SWR 的使用手册

568 阅读3分钟

如果你的 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 点个 ⭐️,这也是我们不断前行的动力 😃。