本文介绍在项目中使用 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 的查询结果
假设我们有两个组件,User 和 Profile. User组件需要在渲染时获取数据,而 Profile 组件和User不村子 父子组件关系,这个时候 Profile 要获取数据的时候,Spreado 就派上了用场。
- 定义获取数据并传播的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,
{}
);
}
-
在
User组件中 使用useUserQuerySpreadOutHook来获取并传播数据.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>
);
}
- 在
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>
);
}
- 在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;
- 使用 Spreado 对react-query 数据的传播就结束了. 详细的代码和Demo 可以在这里看Codesandbox
写在最后
使用 Spreado 传播 reac-query结果是不是非常简单。而且非异步数据也同样可以使用 Spreado 和 Redux 配合使用。
为了更好的学习使用Spreado,可以学习GitHub repo react-easier/spreado,如果觉得小工具有帮助,请给 GitHub repo react-easier/spreado 点个 ⭐️,这也是我们不断前行的动力 😃