React + 项目(从基础到实战) -- 第八期

news2024/11/29 8:51:51

ajax 请求的搭建

  1. 引入mock
  2. AP接口设计
  3. AJAX 通讯

前置知识

  • HTTP 协议 , 前后端通讯的桥梁
  • API : XMLHttpRequest 和 fetch
  • 常用工具axios

mock 引入

Mock.js (mockjs.com)

使用 mockJS

  1. 前端代码中引入 mockJs
  2. 定义要模拟的路由 , 返回结果
  3. mockJs 劫持ajax请求(返回模拟的结果)
import Mock from 'mockjs'

Mock.mock('/api/test', 'get', ()=>{

    return {

        code: 0,

        data: {

           name:"lxy text"

        }

    }

})

使用fetch api 向后端发起请求

 useEffect(()=>{

        fetch('/api/test')

        .then((res)=>{

            console.log("res = ",res)

        })

        .then((err)=>{

            console.log("err = ",err)

        })

  
  
  

    },[])

bug : 发现返回的数据不是我们模拟的
mockjs 劫持失败

在这里插入图片描述

因为mock JS 只能劫持XMLHttpRequest

使用axios(要先安装哦) axios中文文档|axios中文网 | axios (axios-js.com)

  axios.get('/api/test')

        .then(function (response) {

            console.log(response.data.data);

        })

        .catch(function (error) {

            console.log(error);

        });

成功

在这里插入图片描述

总结

  1. 只能劫持XMLHttpRequest 不能劫持fetch ,有局限性
  2. 注意线上环境要注释掉,否则线上请求也被劫持

前端项目中不建议使用 mock JS

node JS + mock JS

将mockJS 用于nodeJS服务端 , 使用它的Random能力

后端操作

  1. 初始化node 环境 npm init -y

  2. 安装mock JS

  3. 安装nodemon
    自定义启动命令
    在这里插入图片描述

  4. 安装 koa
    Koa (koajs) – 基于 Node.js 平台的下一代 web 开发框架 | Koajs 中文文档 (bootcss.com)

这里添加异步函数模拟请求响应的时间差

const Mock = require('mockjs');

  

const Random = Mock.Random;

  

module.exports = [

    {

        url: '/api/question/:id',

        method: 'get',

        response: () => {

            return {

                code: 200,

                data: {

                    id: Random.id(),

                    title: Random.ctitle()

                }

            }

        }

    },

    {

        url: '/api/question',

        method: 'post',

        response: () => {

            return {

                code: 200,

                data: {

                    id: Random.id(),

                    name: Random.cname(),

                }

            }

        }

    }

]
  

const Koa = require('koa');

const Router = require('koa-router');

const mockList = require('./mock/index');

  

const app = new Koa();

const router = new Router();

  

//定义异步函数

async function getRes(fn) {

    return new Promise(resolve => {

        setTimeout(() => {

           const res= fn()

           resolve(res)

        }, 2000)

    })

}

  
  

//注册 mock 路由

mockList.forEach(item => {

    const {url , method , response} = item;

    router[method](url, async ctx => {

        // const res=response();

        //模拟网络请求的加载状态, 2S

        const res = await getRes(response);

        ctx.body = res;

    })

})

  
  

app.use(router.routes());

app.listen(3001) // 监听的端口号

启动成功

localhost:3001/api/question/12

在这里插入图片描述

前端操作

  useEffect(()=>{

        // 跨域

        // > 前端地址:http://localhost:3000

        // > 后端地址:http://localhost:3001

     fetch('http://localhost:3001/api/test')

        .then((res)=>{

            console.log("res = ",res)

        })

        .then((err)=>{

            console.log("err = ",err)

        })

  

    },[])

跨域
前端地址:http://localhost:5173
后端地址:http://localhost:3001

解决vite的跨域问题_vite解决跨域-CSDN博客

发现还是报错

在后端改

在这里插入图片描述

在线mock平台

fast-mock y-api swagger

API 设计

用户API

  1. 登录
  2. 注册
  3. 获取用户信息

问卷api

  1. 创建问卷
  2. 获取单个问卷
  3. 更新问卷
  4. 删除问卷
  5. 查询问卷
  6. 复制问卷

使用Restful API

method: ,
path: ,
request body: ,
responde: ,

用户验证

JWT

统一返回格式

errno , data ,msg

实战

配置axios 基本功能

  1. 创建axios实例
  2. 配置全局的拦截器
import { message } from "antd";

import axios from "axios";

  

//1.创建实例

const instance = axios.create({

    baseURL: 'http://localhost:3001/api/',

    timeout: 1000,//等待一秒

    headers: {'X-Custom-Header': 'foobar'}

  });

  
  
  
  

//2.添加请求拦截器

instance.interceptors.request.use(function () {

    // 在发送请求之前做些什么

    console.log("我要发请求啦");

  }, function () {

    // 对请求错误做些什么

    console.log("请求错误啦");

  });

  

//3.添加响应拦截器

instance.interceptors.response.use(function (res) {

    // 2xx 范围内的状态码都会触发该函数。

    // 对响应数据做点什么

    console.log("我收到响应啦");

    const resData = (res.data || {}) as ResType;

    const {errno,data,msg} = resData;

    if(errno !== 0){

        message.error(msg || "未知错误");

    }

  

    return data as any;

  }, function () {

    // 超出 2xx 范围的状态码都会触发该函数。

    // 对响应错误做点什么

    console.log("响应错误啦");

  });

  
  

  //定义类型

type ResType={

    errno:number,

    data?:ResDataType,

    msg?:string

}

  

type ResDataType={

    [keu:string]: any //可以有任意值,只要key键是string类型

}

  
  
  
  
  

export default instance ;

模拟axios请求

请求函数

import axios , {ResDataType} from "./axios"

  

//获取单个问卷

export async function getQuestinService(id: string): Promise<ResDataType>{

    const url=`/question/${id}`

  

    const data = ( await axios.get(url) ) as ResDataType;

  

    return data;

}

使用

import React,{FC,useEffect} from 'react'

  

import {useParams} from 'react-router-dom';

  

//导入发起请求的函数

import { getQuestinService } from '../../../services/question';

  
  

const Edit : FC = ()=>{

    //获取携带的参数

    const {id = ''} = useParams();

    useEffect(()=>{

        getQuestinService(id);

    },[])

  

    return (

        <>

        <h1>edit  {id}</h1>

        {/* http://localhost:5173/question/edit/20 */}

        </>

    )

}



export default Edit;

报错
TypeError: Cannot read properties of undefined (reading ‘cancelToken’)
TypeError: Cannot read properties of undefined (reading ‘cancelToken‘)_cannot read properties of undefined (reading 'canc-CSDN博客

又报错

message: ‘timeout of 1000ms exceeded’

原来是前端设置了等待一秒,改一下

timeout: 1000 * 10,//等待10秒

页面添加loading效果

自定义

function useLoadQuestionData() {

    const {id = ''} =useParams()

    const [loading,setLoading] = useState(true)

    const [questionData,setQuestionData] = useState({})

  

    useEffect(()=>{

        async function fn()

        {

            const data = await getQuestinService(id)

            setQuestionData(data)

            setLoading(false)

        }

  

        fn()

    },[])

  

    return {loading,questionData}

  
  

}

使用ahooks中的useRequest

  async function load(){

        const data = await getQuestinService(id)

        return data;

    }

  

    const {loading,data,error} =useRequest(load)

  

    return {loading,data,error}

useRequest 与 自定义发请求

自定义请求

  const[questionList,setQuestionList] = useState([])

    const [total ,setTotal] =useState(0)

    useEffect(()=>{

      async function fn()

      {

          //问卷列表数据模拟

        const data= await getQuestinListService()

        const {list=[],total=0} =data

        setQuestionList(list)

        setTotal(total)

     }

     fn()

    },[])

使用useRequest

 const {data={},loading} = useRequest(getQuestinListService)

    const {list=[],total=0} = data

列表增加搜索hook

向后端发起请求的接口

//获取(搜索)问卷列表

export async function getQuestinListService(

    opt:Partial<SearchType>

): Promise<ResDataType>{

    const url='/question'

    const data = ( await axios.get(url,{

        params:opt

    }) ) as ResDataType;

    return data;

}

在这里插入图片描述

自定义hook

import {LIST_SEARCH_PARAM_KEY} from "../constant/index";

import {  useSearchParams } from "react-router-dom";

import { useRequest } from "ahooks";

//导入发起请求的函数

  

import { getQuestinListService } from "../services/question";

  

function useLoadQuestionData() {

    const [searchParams] = useSearchParams();

  
  

    async function load(){

        const keyword=searchParams.get(LIST_SEARCH_PARAM_KEY) || " "

        const data = await getQuestinListService({keyword});

  

        return data;

    }

  

    const {loading,data,error} =useRequest(load,{

        refreshDeps:[searchParams],//刷新的依赖项

    })

  

    return {loading,data,error}

  
  

}

  
  

export default useLoadQuestionData;

使用自定义hook重构list,Star,Trash页面,向后端发请求

发现星标页面并未实现真的搜索功能

在这里插入图片描述

因为后端是随机生成的

在这里插入图片描述

解决

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1603246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SPI 和W25Q128(使用SPI通讯读写W25Q128模块)

SPI 是什么&#xff1f; SPI 是串行外设接口&#xff08; Serial Peripheral Interface &#xff09;的缩写&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上 只占用四根线 &#xff0c;节约了芯片的管脚&#xff0c;同时…

SecureCRT (Mac/Windows)中文---远程连接与管理的安全新选择

SecureCRT是一款功能强大的终端仿真程序&#xff0c;专为连接和管理远程系统而设计。它支持SSH&#xff08;包括SSH1和SSH2&#xff09;协议&#xff0c;确保用户与目标设备之间的通信安全&#xff0c;有效防止网络攻击和窥探。此外&#xff0c;SecureCRT还支持Telnet、Rlogin等…

Jmeter 接口造10w条用户数据

1、将mysql-connector-java-5.1.22-bin.jar放到D:\apache-jmeter-5.5\lib\ext目录下 2、在测试计划中&#xff0c;添加mysql-connector-java-5.1.22-bin.jar包路径 3、添加-线程组-添加-配置元件-jdbc connection configuration 4、配置jdbc连接参数 设置变量名称&#xff1a;…

ASP.NET基于SVG的自动站雨量分析系统

摘 要 SVG是由W3C组织开发的基于可扩展标记语言的一种矢量图形描述语言&#xff0c;已经在互联网上得到了较广泛的应用。为了以图形方式直观地显示雨量数据变化&#xff0c;方便工作人员进行雨量数据的查询及分析&#xff0c;设计了本套基于SVG的雨量分析系统。 该自动站雨量…

基于SSM+Jsp+Mysql的准速达物流管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

wsl安装与日常使用

文章目录 一、前向配置1、搜索功能2、勾选下面几个功能&#xff0c;进行安装二、安装WSL1、打开Windows PowerShell,查找你要安装的linux版本2、选择对应版本进行安装3、输入用户名以及密码 三、配置终端代理1、打开powershell,查看自己的IP把以下信息加入到~/.bashrc中 四、更…

【论文速读】| 大语言模型是边缘情况模糊测试器:通过FuzzGPT测试深度学习库

本次分享论文为&#xff1a;Large Language Models are Edge-Case Fuzzers: Testing Deep Learning Libraries via FuzzGPT 基本信息 原文作者&#xff1a;Yinlin Deng, Chunqiu Steven Xia, Chenyuan Yang, Shizhuo Dylan Zhang, Shujing Yang, Lingming Zhang 作者单位&…

MySQL Explan执行计划详解

Explan执行计划 首先我们采用explan执行计划 执行一条sql&#xff0c;发现返回了12个列&#xff0c;下面会详细解释每一列 1、ID列 id列的值是代表了select语句执行顺序&#xff0c;是和select相关联的&#xff1b;id列的值大的会优先执行&#xff0c;如果id列为空最后执行&a…

python后端相关知识点汇总(十二)

python知识点汇总十二 1、什么是 C/S 和 B/S 架构2、count(1)、count(*)、count(列名)有啥区别&#xff1f;3、如何使用线程池3.1、为什么使用线程池&#xff1f; 4、MySQL 数据库备份命令5、supervisor和Gunicorn6、python项目部署6.1、entrypoint.sh制作6.2、Dockerfile制作6…

可见光相机曝光方式

可见光摄影中的曝光方式主要包括两种&#xff1a;卷帘曝光和全局曝光。它们之间的区别在于曝光过程中传感器或胶片感光部分的工作方式不同&#xff0c;这直接影响到图像捕获的效果和特性。 卷帘曝光&#xff08;Rolling Shutter&#xff09;&#xff1a; 工作原理&#xff1a;在…

Day 16 Linux服务管理和日志管理

服务管理 启动服务&#xff1a;systemctl start 服务名 停止服务&#xff1a;systemctl stop 服务名 重启服务&#xff1a;systemctl restart 服务名 重新加载配置文件&#xff1a;systemctl reload 服务名&#xff08;期间并不停止服务进程&#xff09; 查看服务运行状态…

GAN反演+老照片修复

关于老照片修复~~~~~上图为运行腾讯ARC的模型之后的效果图 其使用的模型&#xff0c;GFP-GAN&#xff0c;Towards Real-World Blind Face Restoration with Generative Facial Prior&#xff0c;理解记录如下&#xff1a; Abstract: In this work, we propose GFP-GAN that …

专业143总分428学硕第一东南大学920专业基础综合考研经验电子信息与通信工程,海洋工程,电路系统,鲁汶,真题,大纲,参考书。

24考研基本已经尘埃落定&#xff0c;总归要为回忆留下点什么。回想起这一年的备考之路&#xff0c;至今仍觉得时间过得很快&#xff0c;有些感到恍惚&#xff0c;似乎不能接受。但是仔细思考一下&#xff0c;这一年经历了很多&#xff0c;走过很多弯路也取得一些阶段性的小成功…

React【Day2】

React表单控制 受控绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 双向绑定 MVVM 报错记录&#xff1a; 错误代码&#xff1a; import { useState } from "react";const App () > {const [value, setValue] useS…

使用Android studio,安卓手机编译安装yolov8部署ncnn,频繁出现编译错误

从编译开始就开始出现错误&#xff0c;解决步骤&#xff1a; 1.降低graddle版本&#xff0c;7.2-bin --->>> 降低为 6.1.1-all #distributionUrlhttps\://services.gradle.org/distributions/gradle-7.2-bin.zip distributionUrlhttps\://services.gradle.org/di…

2024年五一杯数学建模B题思路分析

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

工业自动化,3D视觉技术3C薄片自动化上料

随着制造业的快速发展&#xff0c;3C行业对薄片类零件的上料需求日益增长。传统的上料方式往往依赖于人工操作&#xff0c;效率低下且存在误差。为了解决这一问题&#xff0c;3D视觉技术应运而生&#xff0c;为3C薄片自动化上料提供了强大的技术支持。本文将探讨3D视觉技术如何…

「GO基础」起源与演进

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

分类算法——文章分类(五)

文章分类计算 计算结果 P(C|Chinese,Chinese,Chinese,Tokyo,Japan)-->P(Chinese, Chinese, Chinese, Tokyo, Japan|C) * P(C)/P(Chinese, Chinese, Chinese, Tokyo, Japan) P(Chinese|C)5/8 P(Tokyo|C) 0 P(Japan|C) 0思考&#xff1a;我们计算出来某个概率为0&#xff0c;…

HarmonyOS开发实例:【分布式数据服务】

介绍 分布式数据服务(Distributed Data Service&#xff0c;DDS)为应用程序提供不同设备间数据分布式的能力。通过调用分布式数据接口&#xff0c;应用程序将数据保存到分布式数据库中。通过结合帐号、应用和分布式数据服务对属于不同的应用的数据进行隔离&#xff0c;保证不同…