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

相关推荐
Deepsleep.23 分钟前
react和vue的区别之一
javascript·vue.js·react.js
WEI_Gaot23 分钟前
react19 的项目创建和组件使用
前端·react.js
vvilkim5 小时前
React 与 Vue:两大前端框架的深度对比
vue.js·react.js·前端框架
莫问alicia5 小时前
react 常用钩子 hooks 总结
前端·javascript·react.js
在澳门喝茶的芦竹8 小时前
React高阶组件——React.momo
javascript·react.js
Jet_closer_burning8 小时前
axios封装
前端·javascript·vue.js·react.js·ajax
牧羊狼的狼10 小时前
React.memo 和 useMemo
前端·javascript·react.js
局外人LZ20 小时前
前端项目搭建集锦:vite、vue、react、antd、vant、ts、sass、eslint、prettier、浏览器扩展,开箱即用,附带项目搭建教程
前端·vue.js·react.js
H5开发新纪元1 天前
借助 GitHub Copilot 打造一个完美的 React 消息引用系统:从设计到实现的深度剖析
前端·react.js
哟哟耶耶1 天前
react-09React生命周期
前端·javascript·react.js