Spreado 与 Redux Tooltik, React query的集成

171 阅读2分钟

本文介绍在项目中使用 Redux rtk 与 React query应用如何与 Speado 轻松集成.

前置阅读 Spreado - 轻松地在React 组件中传播状态和数据

本Demo中使用到 Spreado 的 Apis

  • useSpreadOut – React 组件存储对象到 Spreado 中
  • useSpreadIn – React 组件获取 Spreado 中的对象

安装

npm install --save spreado
or
yarn add spreado

初始化 Spreado 和 Redux rtk, React-query

import { useState } from "react";
import "./App.css";
import { Profile } from "./Profile";
import { User } from "./User";
enum Pages {
  User,
  Profile,
}

function App() {
  const [page, setPage] = useState<Pages>(Pages.User);

  return (
    <div className="App">
      <nav>
        <button
          className={page === Pages.Profile ? "active" : ""}
          onClick={() => setPage(Pages.Profile)}
        >
          Profile
        </button>
        <button
          className={page === Pages.User ? "active" : ""}
          onClick={() => setPage(Pages.User)}
        >
          User
        </button>
      </nav>

      <hr style={{ borderTop: "1px solid" }} />

      <div
        style={{
          display: page === Pages.Profile ? "" : "none",
          color: "green",
        }}
      >
        <Profile />
      </div>

      <div
        style={{ display: page === Pages.User ? "" : "none", color: "blue" }}
      >
        <User />
      </div>
    </div>
  );
}

export default App;

使用 Spreado 共享 React-query 的查询结果

假设我们有两个组件,UserProfile. User组件需要在渲染时获取数据,而 Profile 组件和User不村子 父子组件关系,这个时候 Profile 要获取数据的时候,Spreado 就派上了用场。

  1. 定义获取数据并传播的hook,再定义一个获取同一个数据的hook,(demo 使用了 fakerjs 来生成假数据)
import { useQuery } from "react-query";
import { useSpreadIn, useSpreadOut } from "spreado";
import { faker } from "@faker-js/faker";

type User = {
  username: string;
  id?: string;
  avatarUrl?: string;
};

const USER_QUERY_KEY = "USER_QUERY_KEY";

export function useUserQuerySpreadOut() {
  return useSpreadOut(
    USER_QUERY_KEY,
    useQuery<User>([USER_QUERY_KEY], async () => {
      return new Promise<User>((resolve) => {
        setTimeout(() => {
          resolve({
            username: faker.name.fullName(),
            id: faker.database.mongodbObjectId(),
            avatarUrl: faker.internet.avatar(),
          });
        }, Math.floor(Math.random() * 10000));
      });
    })
  );
}

export function useUserQuerySpreadIn() {
  return useSpreadIn<ReturnType<typeof useUserQuerySpreadOut>>(
    USER_QUERY_KEY,
    {}
  );
}
  1. User 组件中 使用 useUserQuerySpreadOut Hook来获取并传播数据.

    Spreado 和React-query的集成除了传递查询结果外,react-query 所有的状态和其它返回值也会一并传递.

import { useUserQuerySpreadOut } from "./queries/useUserQuery";

export function User() {
  const { data: user, isFetching, refetch } = useUserQuerySpreadOut();

  return (
    <div>
      {isFetching ? (
        <p>Loading...</p>
      ) : (
        <>
          <h2>User Page</h2>
          <h3>Username: {user?.username}</h3>
        </>
      )}
      <button disabled={isFetching} onClick={() => refetch()}>
        Refetch
      </button>
    </div>
  );
}


  1. Profile组件中使用 useUserQuerySpreadIn来获取查询结果.
import { useUserQuerySpreadIn } from "./queries/useUserQuery";

export function Profile() {
  const { data: user } = useUserQuerySpreadIn();

  return (
    <div>
      <h2>Profile Page </h2>
      <h3>Username: {user?.username}</h3>
    </div>
  );
}
  1. 在App 中组合这两个组件.
import { useState } from "react";
import "./App.css";
import { Profile } from "./Profile";
import { User } from "./User";

enum Pages {
  User,
  Profile,
}

function App() {
  const [page, setPage] = useState<Pages>(Pages.User);

  return (
    <div className="App">
      <nav>
        <button
          className={page === Pages.Profile ? "active" : ""}
          onClick={() => setPage(Pages.Profile)}
        >
          Profile
        </button>
        <button
          className={page === Pages.User ? "active" : ""}
          onClick={() => setPage(Pages.User)}
        >
          User
        </button>
      </nav>

      <hr style={{ borderTop: "1px solid" }} />

      <div
        style={{
          display: page === Pages.Profile ? "" : "none",
          color: "green",
        }}
      >
        <Profile />
      </div>

      <div
        style={{ display: page === Pages.User ? "" : "none", color: "blue" }}
      >
        <User />
      </div>
    </div>
  );
}

export default App;

  1. 使用 Spreado 对react-query 数据的传播就结束了. 详细的代码和Demo 可以在这里看Codesandbox

写在最后

使用 Spreado 传播 reac-query结果是不是非常简单。而且非异步数据也同样可以使用 Spreado 和 Redux 配合使用。

 

为了更好的学习使用Spreado,可以学习GitHub repo react-easier/spreado,如果觉得小工具有帮助,请给 GitHub repo react-easier/spreado 点个 ⭐️,这也是我们不断前行的动力 😃:v: