创建react项目
react官网推荐创建 react 项目的方式改变了,除了 next.js 还有使用React Router(V7) 这种方式。
npx create-react-router@latest
然后进入项目安装相关依赖
npm i -D mockjs @types/mockjs vite-plugin-mock
npm i -S axios
目录结构:
添加对mockjs 的支持
vite.config.js配置
// vite.config.ts
import { reactRouter } from "@react-router/dev/vite";
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
import { viteMockServe } from "vite-plugin-mock";// 引入
const isDev = process.env.NODE_ENV === "development";// 开发环境使用
export default defineConfig({
plugins: [
tailwindcss(),
reactRouter(),
tsconfigPaths(),
isDev && // 配置
viteMockServe({
mockPath: "mocks",
watchFiles: true,
enable: true,
}),
],
});
mockjs API 配置
// mocks/index.ts
import Mock from "mockjs";
export default [
{
url: "/mock/users",
method: "GET",
timeout: 3000,
response: () => {
const res = Mock.mock({
"list|5": [
{
id: "@guid",
name: "@cname",
email: "@email",
address: "@county(true)",
},
],
});
return res.list;
},
},
];
取消请求的逻辑
// app/routes/home.tsx
import {
useRef,
useEffect,
useActionState,
startTransition,
useState,
} from "react";
import type { Route } from "./+types/home";
export function meta({}: Route.MetaArgs) {
return [
{ title: "取消 http 请求" },
{ name: "description", content: "如何取消 http 请求" },
];
}
export default function Home() {
const controllerRef = useRef<any>(null);
const [data, fetchUsers, isPending] = useActionState(async () => {
try {
controllerRef.current = new AbortController();
const res = await fetch("/mock/users", {
signal: controllerRef.current.signal,
});
const d = await res.json();
console.log(d);
return d;
} catch (error: any) {
if (error.name === "AbortError") {
console.log("Fetch aborted");
} else {
console.error("Fetch error:", error);
}
}
}, null);
return (
<div className="">
<button
className="w-30 cursor-pointer hover:bg-amber-600 rounded-2xl border-amber-900 border-4"
disabled={isPending}
onClick={() => {
startTransition(() => {
fetchUsers();
});
}}
>
Fetch Users
</button>
<button
className="w-40 ml-2 cursor-pointer hover:bg-amber-600 rounded-2xl border-amber-900 border-4"
onClick={() => {
controllerRef.current?.abort();
}}
>
Cancel Fetch Users
</button>
<ul>
{data?.map((d: any) => (
<li key={d.email}>{d.name}</li>
))}
</ul>
</div>
);
}
结果如下: