在 cursor 中开发 react 项目应使用自定义 hook 封装请求逻辑,避免直接调用 fetch/axios 导致状态错乱;需用 abortcontroller 取消旧请求、统一拦截处理 token 和错误、结合 vite 环境变量配置 baseurl,并在组件中安全调用。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

在 Cursor 中开发 React 项目时,直接写 fetch 或 axios 调用会导致逻辑散落、重复处理 loading/error、无法自动取消请求、难以复用——尤其当你频繁切换页面或快速输入触发多次请求时,容易出现状态错乱或内存泄漏。
用自定义 Hook 封装请求逻辑
第一步:在 src/hooks 下新建 useRequest.js 文件。
第二步:导入 useState、useEffect、useRef 和 useCallback,确保能管理状态、副作用、取消能力和参数记忆。
第三步:定义函数签名,接收请求函数(如 fetchUsers)、依赖数组(如 [userId])和配置项({ autoRequest: true, abortPreRequest: true })。
第四步:内部用 useRef 存储 AbortController 实例,每次新请求前调用 abort() → 这一步【必须做,否则旧请求未完成就发起新请求,可能覆盖 setState 导致 UI 显示错误数据】。
第五步:返回对象包含 loading、data、error、run(手动触发)、cancel(主动终止),所有字段都通过 useState 管理,且 run 使用 useCallback 避免子组件重复渲染。
封装一个带拦截的 Axios 实例
方法一:创建 src/utils/request.js
引入 axios,调用 axios.create({ baseURL: '/api', timeout: 5000 }) 创建实例。
配置请求拦截器:在发送前检查是否已登录(读取 localStorage token),若无则跳转登录页 → 这步不加会导致接口 401 后白屏,用户无感知。
配置响应拦截器:统一处理 response.data 提取业务数据体,对 code !== 200 的响应抛出错误(Promise.reject(new Error(msg))),让 useRequest 捕获后更新 error 状态。
方法二:支持环境变量自动切 baseURL
在 vite.config.js 中配置 define 注入 import.meta.env.VITE_API_BASE_URL → 开发用 /api(走 vite 代理),生产用真实域名。
注意:【vite 代理只在 dev 模式生效,build 后失效,务必确认生产环境 nginx 已配置对应反向代理规则】。
在组件中调用封装好的请求
第一步:在组件顶部 import { useRequest } from '@/hooks/useRequest';
第二步:定义请求函数,例如 const fetchPost = () => api.get('/posts');
第三步:调用 const { data, loading, error, run } = useRequest(fetchPost, [], { autoRequest: false });
第四步:用 button 触发 run(),用 useEffect 监听依赖项变化自动重载 → 这种写法比 useEffect + fetch 更安全,因为 useRequest 内部已处理了 abort、防抖、重复请求拦截等边界情况。
第五步:渲染时判断 loading 显示骨架屏,error 显示提示按钮,data 渲染列表 —— 所有状态分支都被显式覆盖,不会遗漏空值或 pending 状态。











