封装useEffect,实现并发请求数据图实时响应

遇到这样一种工作场景:当一个页面需要依赖多个请求并发处理时,而显示数据需要实时变动(根据传入的参数变动而实时更改)

起初我没有想到那么多时我是这样写的

 const escortExperienceParm = useSelector((state: RootState) => state.escortExperienceParam); //伴游经验参数
  const escortSumParm = useSelector((state: RootState) => state.escortSum); //伴游总数据
  const escortTipParm = useSelector((state: RootState) => state.escortTip); //伴游打赏参数
  const escortRewar = useSelector((state: RootState) => state.escortRewar); //伴游报酬参数
  const escortNumOrder = useSelector((state: RootState) => state.escortNumOrder);
  const escortType = useSelector((state: RootState) => state.escortType);

  // 定义状态和数据获取
  const [escortSumData, setEscortSumData] = useState<TableDataRes>();
  const [experienceData, setExperienceData] = useState<TableDataRes>();
  const [escortTiData, setEscortTipData] = useState<TableDataRes>();
  const [rewardData, setRewardData] = useState<TableDataRes>();
  const [numOrderData, setNumOrderData] = useState<TableDataRes>();
  const [escortTypeData, setEscortTypeData] = useState<TableDataRes>();

  useEffect(() => {
    const fetchData = async () => {
      try {
        setEscortSumData(await escortGetAccompanyTravelData(escortSumParm));
        setEscortTipData(await escortGetAccompanyTravelGift(escortTipParm));
        setRewardData(await escortGetGetFee(escortRewar));
        setNumOrderData(await escortGetPublicAndTarget(escortNumOrder));
        setEscortTypeData(await escortGetType(escortType));
      } catch (error) {
        console.error('Error fetching data', error);
      }
    };

    fetchData();
  }, [escortSumParm, escortExperienceParm, escortTipParm,escortType,escortNumOrder]);

首先我需要取到redux状态参数,然后定义页面状态,然后在根据参数获取数据再更改状态。这时我注意到这个场景我会多次这样使用,会不会有胆太复杂了。而且好像依赖的参数一变动所有的数据重新请求?这样不对!

第一种解决方法:每个请求使用一个useEffect,依赖各自的参数.。(这样问题可以解决,但是正如我刚才所说,这个会是个多场景业务,,业务问题得以解决,但是代码重复会特别多。)果断舍弃这种方案。

仔细想想可不可以封装一个请求函数,传入一个请求api和参数,参数变化是自动执行函数?可行!开搞

import { useEffect, useState } from 'react';

/**
 * 自定义钩子用于处理异步数据请求
 * @param asyncFunction - 执行异步操作的函数
 * @param dependencies - 依赖数组,决定何时重新执行异步操作
 * @returns 包含数据、加载状态和错误信息的对象
 */
const useAsyncEffect = (asyncFunction: () => Promise<any>, dependencies: any[]) => {
  const [data, setData] = useState<any>(undefined);

  useEffect(
    () => {
      let isMounted = true;

      asyncFunction().then(result => {
        if (isMounted) {
          setData(result);
        }
      });

      return () => {
        isMounted = false;
      };
    },
    dependencies
  );

  return data;
};

export default useAsyncEffect;

这样简单的封装了一下useEffect,代码结构比较简单不做过多解释。

实事实上这个有个bug,这里如果依赖项是个简单数据类型监听到自动触发,可如果是个引用数据类型呢?实际上useEffect它只是浅层监听,该如何解决呢?这有涉及到深浅拷贝的知识面了,解决方案如下

  // 使用 JSON.stringify 序列化依赖项
    },
    dependencies.map(dep => JSON.stringify(dep))

到此函数封装结束接下来看我简化后的代码

  const escortExperienceParm = useSelector((state: RootState) => state.escortExperienceParam); //伴游经验参数
  const escortSumParm = useSelector((state: RootState) => state.escortSum); //伴游总数据
  const escortTipParm = useSelector((state: RootState) => state.escortTip); //伴游打赏参数
  const escortRewar = useSelector((state: RootState) => state.escortRewar); //伴游报酬参数
  const escortNumOrder = useSelector((state: RootState) => state.escortNumOrder);
  const escortType = useSelector((state: RootState) => state.escortType);
  const escortSumData = useAsyncEffect(() => escortGetAccompanyTravelData(escortSumParm), [escortSumParm]);
  const experienceData1 = useAsyncEffect(() => escortGetExperience(escortExperienceParm), [escortExperienceParm]);
  const escortTiData = useAsyncEffect(() => escortGetAccompanyTravelGift(escortTipParm), [escortTipParm]);
  const rewardData = useAsyncEffect(() => escortGetGetFee(escortRewar), [escortRewar]);
  const numOrderData = useAsyncEffect(() => escortGetPublicAndTarget(escortNumOrder), [escortNumOrder]);
  const escortTypeData = useAsyncEffect(() => escortGetType(escortType), [escortType]);

依然需要取到redux的状态,但是后续就不会有过多的定义修改操作了。最后关于这个方法如果你有更好的解决方法的话请指出,我们一起讨论 

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值