React入门(三)-封装 Fetch 以及增加接口模拟请求

封装 Fetch 以及增加接口模拟请求

一、软件安装

为了实现接口模拟和请求封装,我们需要安装以下依赖:

  1. 安装 Mock.js

    Mock.js 用于生成模拟数据:

    bash 复制代码
    npm install mockjs --save-dev
  2. 安装 Express

    Express 用于搭建模拟后端服务:

    bash 复制代码
    npm install express
  3. 安装 Concurrently

    Concurrently 用于同时启动前端项目和 Express 服务:

    bash 复制代码
    npm install concurrently --save-dev

二、封装 Fetch

为了简化 Fetch 的使用并处理常见的请求逻辑,我们对 Fetch 进行了 Promise 封装。以下是封装代码:

typescript 复制代码
class FetchUtil {
  /**
   * 发送 POST 请求
   * @param url 请求的 URL
   * @param body 请求体数据
   * @param headers 自定义请求头(可选)
   * @returns Promise<any> 返回一个 Promise,解析为响应数据
   */
  static post<T>(
    url: string,
    body: T,
    headers: Record<string, string> = {}
  ): Promise<any> {
    return new Promise((resolve, reject) => {
      fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json', // 默认 Content-Type
          ...headers // 合并自定义请求头
        },
        body: JSON.stringify(body) // 将 body 转换为 JSON 字符串
      })
        .then((response) => {
          if (!response.ok) {
            reject(new Error(`HTTP error! status: ${response.status}`));
          }
          return response.json();
        })
        .then((data) => resolve(data)) // 解析响应数据为 JSON
        .catch((error) => {
          console.error('Error in POST request:', error);
          reject(error); // 捕获并传递错误
        });
    });
  }
}

export default FetchUtil;

优化建议

在实际项目中,可以进一步优化封装,例如提取 URL 中的 IP 和端口,作为静态配置,以区分开发、测试和生产环境。

三、模拟后端数据

最初尝试使用 Mock.js 模拟接口,但发现请求始终返回 404 错误。经过排查,推测是 React 路由拦截了 /api 请求,导致 Mock.js 无法生效。因此,我们改用 Express 模拟后端服务。

  1. Vite 反向代理配置

    vite.config.ts 中配置反向代理,将 /api 请求转发到 Express 服务:

    typescript 复制代码
    export default defineConfig({
      plugins: [react()],
      resolve: {
        alias: {
          '@': path.resolve(__dirname, './src'), // 定义 @ 为 src 目录
        },
      },
      server: {
        proxy: {
          '/api': {
            target: 'http://localhost:5000', // 后端服务地址
            changeOrigin: true, // 修改请求头中的 Origin
          },
        },
      },
    });
  2. 修改启动脚本

    package.json 中添加 Concurrently 脚本,同时启动 Vite 和 Express 服务:

    json 复制代码
    "scripts": {
      "dev": "concurrently \"vite\" \"node src/mock/mock-server.js\"",
      "build": "tsc -b && vite build",
      "lint": "eslint .",
      "preview": "vite preview"
    }
  3. Express 模拟 API 服务

    使用 Express 搭建模拟后端服务:

    typescript 复制代码
    import express from 'express';
    import Mock from 'mockjs';
    
    const app = express();
    const PORT = 5000;
    
    app.use(express.json());
    
    // 模拟登录接口
    app.post('/api/login', (req, res) => {
      const { username, password } = req.body;
      if (username === 'admin' && password === '123456') {
        res.json({
          success: true,
          message: '登录成功!',
          data: { token: 'mock-token' },
        });
      } else {
        res.status(401).json({
          success: false,
          message: '用户名或密码错误!',
        });
      }
    });
    
    // 模拟其他接口
    app.get('/api/data', (req, res) => {
      res.json({
        success: true,
        data: Mock.mock({
          'list|5': ['@id'],
        }),
      });
    });
    
    // 启动服务
    app.listen(PORT, () => {
      console.log(`Mock server is running on http://localhost:${PORT}`);
    });
  4. 集成 FetchUtils

    login.tsx 中使用封装的 FetchUtils 发送请求:

    typescript 复制代码
    FetchUtil.post('/api/login', body)
      .then((data) => {
        setLoading(false);
        if (data.success) {
          message.success('登录成功!');
          SessionStorageUtil.setItem('user', { username: values.username });
          navigate('/dashboard'); // 登录成功后跳转到 Dashboard
        } else {
          message.error('用户名或密码错误!');
        }
      })
      .catch((error) => {
        setLoading(false);
        message.error('登录失败,请稍后再试!');
        console.error('Login error:', error);
      });

四、总结

在实现接口模拟的过程中,最初尝试使用 Mock.js,但发现请求始终返回 404 错误。经过排查,推测是因为 React 路由拦截了 /api 请求,导致 Mock.js 无法生效。为了解决这一问题,改为使用 Express 搭建模拟后端服务,并通过 Vite 的反向代理配置将请求转发到 Express 服务。最终,成功实现了接口模拟。

为了同时启动前端项目和 Express 服务,我们使用了 Concurrently 工具,并修改了 package.json 中的启动脚本:

json 复制代码
"dev": "concurrently \"vite\" \"node src/mock/mock-server.js\""

通过这一方案,我们不仅解决了 Mock.js 的问题,还为项目提供了一个灵活的接口模拟方案。虽然对 Mock.js 的问题尚未完全理解,但 Express 的方案已经满足了当前的开发需求。

五、代码资源

项目完整代码托管于 Gitee,地址为:gitee.com/animal-fox_...

相关推荐
yuanyxh10 小时前
静默打印程序实现
前端·react.js·electron
前端老宋Running11 小时前
“受控组件”的诅咒:为什么你需要 React Hook Form + Zod 来拯救你的键盘?
前端·javascript·react.js
风止何安啊11 小时前
拿捏 React 组件通讯:从父子到跨组件的「传功秘籍」
前端·react.js·面试
韭菜炒大葱12 小时前
React 新手村通关指南:状态、组件与魔法 UI 🧙‍♂️
前端·javascript·react.js
用户120391129472619 小时前
从零掌握 React JSX:为什么它让前端开发像搭积木一样简单?
前端·react.js·面试
3秒一个大2 天前
JSX 基本语法与 React 组件化思想
前端·react.js
HexCIer2 天前
Arco Design 停摆!字节跳动 UI 库凉了?
react.js·前端框架
风止何安啊2 天前
React 入门秘籍:像搭积木一样写网页,JSX 让开发爽到飞起!
前端·react.js·前端框架
whyfail2 天前
React原理(暴力版)
前端·react.js
Crazy_Urus2 天前
深入解析 React 史上最严重的 RCE 漏洞 CVE-2025-55182
前端·安全·react.js