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_...

相关推荐
来碗螺狮粉2 小时前
CSR mode下基于react+i18next实践国际化多语言解决方案
react.js
Alang2 小时前
记一次错误使用 useEffect 导致电脑差点“报废”
前端·react.js
关山月3 小时前
🌟 正确管理深层嵌套的 React 组件
react.js
lisw054 小时前
排序算法可视化工具——基于React的交互式应用
算法·react.js·排序算法
__不想说话__4 小时前
面试官问我React Router原理,我掏出了平底锅…
前端·javascript·react.js
DevinJohw4 小时前
为什么我选择[email protected]
react.js·vite
尽-欢7 小时前
以太坊DApp开发脚手架:Scaffold-ETH 2 详细介绍与搭建教程
react.js·typescript·web3·区块链
枫荷10 小时前
彻底理解react中useSyncExternalStore的用法
前端·react.js
全栈派森11 小时前
React Hooks 你知道哪些 ?
前端·react.js
百锦再1 天前
React编程的核心概念:发布-订阅模型、背压与异步非阻塞
前端·javascript·react.js·前端框架·json·ecmascript·html5