返回顶部
首页 > 资讯 > 精选 >ahooks useRequest怎么使用
  • 407
分享到

ahooks useRequest怎么使用

2023-07-05 11:07:14 407人浏览 安东尼
摘要

这篇文章主要介绍“ahooks useRequest怎么使用”,在日常操作中,相信很多人在ahooks useRequest怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ahook

这篇文章主要介绍“ahooks useRequest怎么使用”,在日常操作中,相信很多人在ahooks useRequest怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ahooks useRequest怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

基础版(雏形)

先上代码:

useRequest.ts

interface UseRequestOptionsProps {    initialData?: object;    onSuccess?: (res: any) => void;}const useRequest = (  requestFn: (    initialData?: object | string | [],  ) => Promise<SetStateAction<any>>,  options: UseRequestOptionsProps,) => {  const [data, setData] = useState<SetStateAction<any>>(null);  const [loading, setLoading] = useState<boolean>(false);  const [error, setError] = useState<string | null>(null);  const { initialData, onSuccess } = options;  useEffect(() => {    setLoading(true);    setError(null);    setData(null);    request();  }, [requestFn]);  // useRequest业务逻辑  const request = async () => {    try {      const res = await requestFn(initialData);      setData(res);      // 请求成功响应回调      onSuccess && onSuccess(res);    } catch (err) {      err && setError(JSON.stringify(err));    } finally {      setLoading(false);    }  };  return { data, loading, error };};export default useRequest;

使用

const { data, loading, error } = useRequest(    queryCompensatoryOrderSituation,    {        initialData: {            compensatoryId,        }        onSuccess: (res) => {            console.log('success request!', res);        },    },);

useRequest 对于请求函数的写法并无过多要求,只要是一个异步function且返回一个promise对象,即可传入useRequest的第一个参数中,而第二个参数则是一系列的可选配置项,雏形版本我们暂时只支持onSuccess

手动触发

代码改造后:

useRequest.ts

interface UseRequestOptionsProps {    manual?: boolean;    initialData?: object;    onSuccess?: (res: any) => void;}const useRequest = (  requestFn: (    initialData?: object | string | [],  ) => Promise<SetStateAction<any>>,  options: UseRequestOptionsProps,) => {  const [data, setData] = useState<SetStateAction<any>>(null);  const [loading, setLoading] = useState<boolean>(false);  const [error, setError] = useState<string | null>(null);  const { manual, initialData, onSuccess } = options;  useEffect(() => {    setLoading(true);    setError(null);    setData(null);    !manual && request();  }, [manual]);  // useRequest业务逻辑  const request = async () => {    try {      const res = await requestFn(initialData);      setData(res);      // 请求成功响应回调      onSuccess && onSuccess(res);    } catch (err) {      err && setError(jsON.stringify(err));    } finally {      setLoading(false);    }  };  return { data, loading, error, request };};export default useRequest;

使用

const { data, loading, error, request } = useRequest(    queryCompensatoryOrderSituation,    {        manual: true,        initialData: {            compensatoryId,        },        onSuccess: (res) => {            console.log('success request!', res);        },    },);request();

手动执行的逻辑主要是根据manual参数砍掉useRequest mount阶段的渲染请求,把执行请求的能力暴露出去,在页面中去手动调用request()来触发。

轮询与手动取消

代码改造后:

useRequest.ts

interface UseRequestOptionsProps {    manual?: boolean;    initialData?: object;    pollingInterval?: number | null;    onSuccess?: (res: any) => void;}const useRequest = (  requestFn: (    initialData?: object | string | [],  ) => Promise<SetStateAction<any>>,  options: UseRequestOptionsProps,) => {  const [data, setData] = useState<SetStateAction<any>>(null);  const [loading, setLoading] = useState<boolean>(false);  const [error, setError] = useState<string | null>(null);  const status = useRef<boolean>(false);  const pollingIntervalTimer = useRef<nodejs.Timer | null>(null);  const { manual, initialData, pollingInterval, onSuccess } = options;  useEffect(() => {    setLoading(true);    setError(null);    setData(null);    !manual && request();  }, [manual]);  // useRequest业务逻辑  const request = async () => {   try {      !status.current && (status.current = true);      if (pollingInterval && status.current) {        pollingIntervalTimer.current = setTimeout(() => {          status.current && request();        }, pollingInterval);      }      const res = await requestFn(initialData);      setData(res);      // 请求成功响应回调      onSuccess && onSuccess(res);    } catch (err) {      err && setError(JSON.stringify(err));    } finally {      setLoading(false);    }  };  return { data, loading, error, request, cancel };};// 取消const cancel = () => {  if (pollingIntervalTimer.current) {    clearTimeout(pollingIntervalTimer.current);    pollingIntervalTimer.current = null;    status.current && (status.current = false);  }};export default useRequest;

使用

const { data, loading, error, request, cancel } = useRequest(    queryCompensatoryOrderSituation,    {        manual: true,        initialData: {            compensatoryId,        },        pollingInterval: 1000,        onSuccess: (res) => {            console.log('success request!', res);        },    },);request();...// 轮询到理想数据后cancel();

轮询的支持在hook中主要用到了timer setTimeout递归思路,同时给出一个status状态值判断是否在轮询中,当调用端执行cancel()status则为false;当轮询开始,则statustrue

cancel()的能力 主要也是取消了timer的递归请求逻辑,并且轮询的业务场景和manual: true配合很多。

依赖请求(串型请求)

代码改造后:

useRequest.ts

interface UseRequestOptionsProps {    manual?: boolean;    initialData?: object;    pollingInterval?: number | null;    ready?: boolean;    onSuccess?: (res: any) => void;}const useRequest = (  requestFn: (    initialData?: object | string | [],  ) => Promise<SetStateAction<any>>,  options: UseRequestOptionsProps,) => {  const [data, setData] = useState<SetStateAction<any>>(null);  const [loading, setLoading] = useState<boolean>(false);  const [error, setError] = useState<string | null>(null);  const status = useRef<boolean>(false);  const pollingIntervalTimer = useRef<nodeJS.Timer | null>(null);  const {    manual,    initialData,    pollingInterval,    ready = true,    onSuccess,  } = options;  useEffect(() => {    setLoading(true);    setError(null);    setData(null);    !manual && ready && request();  }, [manual, ready]);  // useRequest业务逻辑  const request = async () => {   try {      !status.current && (status.current = true);      if (pollingInterval && status.current) {        pollingIntervalTimer.current = setTimeout(() => {          status.current && request();        }, pollingInterval);      }      const res = await requestFn(initialData);      setData(res);      // 请求成功响应回调      onSuccess && onSuccess(res);    } catch (err) {      err && setError(JSON.stringify(err));    } finally {      setLoading(false);    }  };  return { data, loading, error, request, cancel };};// 取消const cancel = () => {  if (pollingIntervalTimer.current) {    clearTimeout(pollingIntervalTimer.current);    pollingIntervalTimer.current = null;    status.current && (status.current = false);  }};export default useRequest;

使用

const [mountLoading, setMountLoading] = useState<boolean>(false);useEffect(() => {    setMountLoading(true);}, [2000])const { data, loading, error, request, cancel } = useRequest(    queryCompensatoryOrderSituation,    {        initialData: {            compensatoryId,        },        pollingInterval: 1000,        ready: mountLoading,        onSuccess: (res) => {            console.log('success request!', res);        },    },);

依赖请求的思路就是在hook中加入一个ready字段,也是在基于manual一层的限制后又加了一层,来判断是否在hook加载时是否做默认请求,而当option中的ready更新(为true)时,hook自动更新从而发起请求。

常用于页面中A请求完成后执行B请求,B请求的ready字段依赖于A请求的data/loading字段。

防抖与节流

防抖和节流的实现比较简单,依赖于lodash库,包装了一下request函数的请求内容。

代码如下:

useRequest.ts

interface UseRequestOptionsProps {    manual?: boolean;    initialData?: object;    pollingInterval?: number | null;    ready?: boolean;    debounceInterval?: number;    throttleInterval?: number;    onSuccess?: (res: any) => void;}const useRequest = (  requestFn: (    initialData?: object | string | [],  ) => Promise<SetStateAction<any>>,  options: UseRequestOptionsProps,) => {  const [data, setData] = useState<SetStateAction<any>>(null);  const [loading, setLoading] = useState<boolean>(false);  const [error, setError] = useState<string | null>(null);  const status = useRef<boolean>(false);  const pollingIntervalTimer = useRef<NodeJS.Timer | null>(null);  const {    manual,    initialData,    pollingInterval,    ready = true,    debounceInterval,    throttleInterval    onSuccess,  } = options;  useEffect(() => {    setLoading(true);    setError(null);    setData(null);    !manual && ready && request();  }, [manual, ready]); //  请求 const request = () => {  if (debounceInterval) {    lodash.debounce(requestDoing, debounceInterval)();  } else if (throttleInterval) {    lodash.throttle(requestDoing, throttleInterval)();  } else {    requestDoing();  }};// useRequest业务逻辑const requestDoing = async () => {  try {    !status.current && (status.current = true);    if (pollingInterval && status.current) {      pollingIntervalTimer.current = setTimeout(() => {        status.current && request();      }, pollingInterval);    }    const res = await requestFn(initialData);    setData(res);    // 请求成功响应回调    onSuccess && onSuccess(res);  } catch (err) {    err && setError(JSON.stringify(err));  } finally {    setLoading(false);  }};// 取消const cancel = () => {  if (pollingIntervalTimer.current) {    clearTimeout(pollingIntervalTimer.current);    pollingIntervalTimer.current = null;    status.current && (status.current = false);  }};export default useRequest;

使用

const { data, loading, error, request, cancel } = useRequest(    queryCompensatoryOrderSituation,    {        manual: true,        initialData: {            compensatoryId,        },        debounceInterval: 1000,     // 防抖        throttleInterval: 1000,     // 节流        onSuccess: (res) => {            console.log('success request!', res);        },    },);for(let i = 0; i < 10000; i++) {    request();}

hook中,通过lodash.debounce/lodash.throttle来包装request函数主体,通过option中的判断来执行对应的包装体函数。

缓存与依赖更新

改造后的代码(最终代码)如下:

useRequest.ts

import {  useState,  useEffect,  useRef,  SetStateAction,  useCallback,} from 'React';import lodash from 'lodash';interface UseRequestOptionsProps {    manual?: boolean;    initialData?: object;    pollingInterval?: number | null;    ready?: boolean;    debounceInterval?: number;    throttleInterval?: number;    loadingDelay?: number;    refreshDeps?: any[];    onSuccess?: (res: any) => void;}const useRequest = (  requestFn: (    initialData?: object | string | [],  ) => Promise<SetStateAction<any>>,  options: UseRequestOptionsProps,) => {  const [data, setData] = useState<SetStateAction<any>>(null);  const [loading, setLoading] = useState<boolean>(false);  const [error, setError] = useState<string | null>(null);  const status = useRef<boolean>(false);  const pollingIntervalTimer = useRef<NodeJS.Timer | null>(null);  const {    manual,    initialData,    pollingInterval,    ready = true,    debounceInterval,    throttleInterval,    loadingDelay,    refreshDeps,    onSuccess,  } = options;  useEffect(() => {    if (loadingDelay) {      setTimeout(() => {        status && setLoading(true);      }, loadingDelay);    }    setError(null);    setData(null);    // 手动触发request    !manual && ready && request();  }, [manual, ready, ...(Array.isArray(refreshDeps) ? refreshDeps : [])]);  //  请求  const request = () => {    if (debounceInterval) {      lodash.debounce(requestDoing, debounceInterval)();    } else if (throttleInterval) {      lodash.throttle(requestDoing, throttleInterval)();    } else {      requestDoing();    }  };  // useRequest业务逻辑  const requestDoing = async () => {    try {      !status.current && (status.current = true);      if (pollingInterval && status.current) {        pollingIntervalTimer.current = setTimeout(() => {          status.current && request();        }, pollingInterval);      }      const res = await requestFn(initialData);      setData(res);      // 请求成功响应回调      onSuccess && onSuccess(res);    } catch (err) {      err && setError(JSON.stringify(err));    } finally {      setLoading(false);    }  };  // 取消  const cancel = () => {    if (pollingIntervalTimer.current) {      clearTimeout(pollingIntervalTimer.current);      pollingIntervalTimer.current = null;      status.current && (status.current = false);    }  };  // 缓存  const cachedFetchData = useCallback(() => data, [data]);  return { data, loading, error, request, cancel, cachedFetchData };};export default useRequest;

使用

const [mountLoading, setMountLoading] = useState<boolean>(false);const [updateLoading, setUpdateLoading] = useState<boolean>(false);setTimeout(() => {    setMountLoading(true);}, 1000);setTimeout(() => {    setUpdateLoading(true);}, 2000);const { data, loading, error, request, cancel, cachedFetchData } = useRequest(    queryCompensatoryOrderSituation,    {        manual: true,        initialData: {            compensatoryId,        },        debounceInterval: 1000,     // 防抖        throttleInterval: 1000,     // 节流        refreshDeps: [mountLoading, updateLoading],        onSuccess: (res) => {            console.log('success request!', res);        },    },);

缓存的主体思路是在useRequest中拿到第一次数据后通过useCallback来透出data依赖来保存,同时向外暴露一个cachedFetchData来过渡datanull到请求到接口数据的过程。

依赖更新的思路则是在页面中给useRequest一系列依赖状态一并加入在hook的请求副作用中,监听到页面中依赖改变,则重新请求,具体实现则是refreshDeps参数。

到此,关于“ahooks useRequest怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: ahooks useRequest怎么使用

本文链接: https://lsjlt.com/news/351240.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • ahooks useRequest怎么使用
    这篇文章主要介绍“ahooks useRequest怎么使用”,在日常操作中,相信很多人在ahooks useRequest怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ahook...
    99+
    2023-07-05
  • ahooks正式发布React Hooks工具库怎么使用
    今天小编给大家分享一下ahooks正式发布React Hooks工具库怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了...
    99+
    2023-07-02
  • ahooks怎么解决用户多次提交问题
    这篇文章主要介绍“ahooks怎么解决用户多次提交问题”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“ahooks怎么解决用户多次提交问题”文章能帮助大家解决问题。场景试想一下,有这么一个场景,有一个...
    99+
    2023-07-02
  • myeclipse怎么使用
    myeclipse怎么使用?首先双击打开软件,主界面如图二所示然后点击文件---->新建---->Java项目在项目名那里输入你要新建的项目名称,名称随意。名称输入完之后直接点击完成...
    99+
    2022-02-23
    java教程 myeclipse
  • 怎么使用SQLite3
    这篇文章主要讲解了“怎么使用SQLite3”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用SQLite3”吧!开始使用这个功能强大且通用的数据库吧。应...
    99+
    2024-04-02
  • 怎么使用IndexedDB
    这篇文章主要讲解了“怎么使用IndexedDB”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用IndexedDB”吧!深入研究IndexedDB AP...
    99+
    2024-04-02
  • 怎么使用hanganalyze
    本篇内容主要讲解“怎么使用hanganalyze”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用hanganalyze”吧!hanganalyze 和sy...
    99+
    2024-04-02
  • 怎么使用pg_rewind
    本篇内容主要讲解“怎么使用pg_rewind”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用pg_rewind”吧!pg_rewind  是po...
    99+
    2024-04-02
  • 怎么使用DBV
    这篇文章主要介绍“怎么使用DBV”,在日常操作中,相信很多人在怎么使用DBV问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么使用DBV”的疑惑有所帮助!接下来,请跟着小编一...
    99+
    2024-04-02
  • 怎么使用RMAN
    本篇内容介绍了“怎么使用RMAN”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!RMAN的备份脚本可以存储在...
    99+
    2024-04-02
  • 怎么使用MindMaster
    本篇内容主要讲解“怎么使用MindMaster”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用MindMaster”吧!MindMaster可谓是思维导图...
    99+
    2024-04-02
  • Redis怎么使用
    这篇文章给大家分享的是有关Redis怎么使用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、Redis简介 什么是Redis?全称:REmote DIctionary Serv...
    99+
    2024-04-02
  • logminer怎么使用
    这篇文章主要讲解了“logminer怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“logminer怎么使用”吧! Log...
    99+
    2024-04-02
  • MySQL怎么使用
    这篇文章主要介绍MySQL怎么使用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、SQL速成  以下是一些重要的SQL快速参考,有关SQL的语法和在标准SQL上增加的特性,请查询M...
    99+
    2024-04-02
  • 怎么使用NTVS
    本篇内容介绍了“怎么使用NTVS”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!就在你认为Redmond不可...
    99+
    2024-04-02
  • 怎么使用Json
    本篇内容主要讲解“怎么使用Json”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Json”吧!Json一般用在少量的数据处理。因为格式简单,操作方便,而...
    99+
    2024-04-02
  • 怎么使用Dart
    本篇内容介绍了“怎么使用Dart”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!下面是简单的Hello Wo...
    99+
    2024-04-02
  • section怎么使用
    今天小编给大家分享一下section怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。...
    99+
    2024-04-02
  • 怎么使用Sass
    这篇“怎么使用Sass”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用Sass”文章...
    99+
    2024-04-02
  • 怎么使用Binlog
    本篇内容介绍了“怎么使用Binlog”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!不知道是否你还在为下面的...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作