繁体   English   中英

如何使用 useEffect 挂钩停止自动重新渲染组件?

[英]How to stop auto re-render on components by using useEffect hook?

我正在使用useEffect钩子,我有两种状态。
两种状态相互依赖; 这意味着当我更改一个basecurrency时,另一个totalamount totalamount 也会更新,反之亦然。

每个 state 都有不同的函数,当状态改变时会调用这些函数。
最初,两种状态都设置为值 0。

挑战
每当加载组件时,由于 state 更改并且无法输入任何输入,页面会不断重新呈现。

 useEffect(() => {
    getRequest("/user/get-user-details")
      .then(d => {
        if (d.code == 1) {
          localStorage.setItem("username", `${d.user.name}`);
          setuseremail(d.user.email);
          setusernumber(d.user.mobileNumber);

          postEwalletRequest("showEWalletBalance", {
            wallet_id: d.user.mobileNumber
          })
            .then(res => {
              console.log(res);
              if (res.status == 1) {
                setballance(res.data.balance);
              }
            })
            .catch(error => {
              console.log(error);
            });
    inclusiveTask();
    exclusiveTask();
  }, [basecurrency,totalamount]);

这些是功能:

const inclusiveTask=()=>{
  getRequest("/get-all-conversionPricelistforconsumer")
    .then(res => {
      setCurrList(res.saveConversionPriceList);
      setExchangeRate(res.saveConversionPriceList[0].amount);
      const converstionPrice = basecurrency * exchangeprice;
      // console.log("convert", converstionPrice);

      setconvertCurrency(converstionPrice);
      console.log("setconvertCurrency", convertcurrency);
      const Amount = `${
        converstionPrice - (converstionPrice * gatewaycharge) / 100
      }`;
      setTotalAmount(Amount);
      const transfee = Amount - converstionPrice;
      setChargeAmount(transfee);
      console.log("Amount", Amount);
      console.log("transfee", transfee);
    })
    .catch(error => {
      console.log(error);
    });

 }

const exclusiveTask = () => {
  getRequest("/get-all-conversionPricelistforconsumer")
   .then(res => {
     setCurrList(res.saveConversionPriceList);
     setExchangeRate(res.saveConversionPriceList[0].amount);
     const Extotal= totalamount/exchangeprice;//100cad
     console.log("Extotal", Extotal);
     const ExclufeeAmount = `${
       totalamount - (totalamount * gatewaycharge) / 100
     }`; //28500
     console.log("ExclufeeAmount", ExclufeeAmount);
     const excluService = totalamount -  ExclufeeAmount;//1500

     const extracharge = excluService / exchangeprice;//5
     console.log("extracharge", extracharge);

     const TotalExclusive = Extotal + extracharge;
     console.log("TotalExclusive", TotalExclusive);
     setCurrency(TotalExclusive);
    
   })
   .catch(error => {
     console.log(error);
   });
};

请提出任何解决方案来帮助我解决此问题。

只需检查您的值是否更改过一次,如果发生了 - 使用 return 语句来防止循环。 您还可以将代码拆分为两个单独的 useEffects,以使代码更清晰、更容易使用。

下面是一些例子: 在此处输入图像描述

认为您可能正在寻找这样的公式,但是从这样一个庞大的问题中很难分辨。

这里的想法是

  • getUserDetails返回用户详细信息的 promise
  • getConversionPriceList返回一个 promise 的价目表数据(以前在 inclusiveTask/exclusiveTask 函数中)
  • inclusiveTaskexclusiveTask是简单的非异步函数,它们只是做数学运算

这些是这样连接的:

  • 第一个useEffect没有依赖关系,即它只运行一次,当组件安装时。 它调用用户详细信息和价格函数并将这些位存储在 state 中。
  • 第二个useEffect取决于用户详细信息和价目表,以及基础货币和金额的 state(不管是什么,我不知道你的业务逻辑)。 它有一个守卫让它在加载效果完成之前不做任何事情。
  • 渲染只是说“正在加载”,直到所需的 state 准备好,然后它毫不客气地将计算结果转储为 JSON(如果有)。
async function getUserDetails() {
  const d = await getRequest("/user/get-user-details");
  if (d.code !== 1) {
    return undefined;
  }
  localStorage.setItem("username", `${d.user.name}`);
  const retVal = {
    username: d.user.name,
    email: d.user.email,
    mobileNumber: d.user.mobileNumber,
    balance: undefined,
  };
  const res = await postEwalletRequest("showEWalletBalance", {
    wallet_id: d.user.mobileNumber,
  });
  if (res.status === 1) {
    retVal.balance = res.data.balance;
  }
  return retVal;
}

async function getConversionPriceList() {
  const res = await getRequest("/get-all-conversionPricelistforconsumer");
  return {
    currList: res.saveConversionPriceList,
    exchangeRate: res.saveConversionPriceList[0].amount,
  };
}

function inclusiveTask(basecurrency, exchangeprice, gatewaycharge) {
  const converstionPrice = basecurrency * exchangeprice;
  const Amount =
    converstionPrice - (converstionPrice * gatewaycharge) / 100;
  const transfee = Amount - converstionPrice;
  return { converstionPrice, Amount, transfee };
}

function exclusiveTask(totalamount, exchangeprice, gatewaycharge) {
  const Extotal = totalamount / exchangeprice; //100cad
  const ExclufeeAmount = totalamount - (totalamount * gatewaycharge) / 100; //28500
  const excluService = totalamount - ExclufeeAmount; //1500
  const extracharge = excluService / exchangeprice; //5
  const TotalExclusive = Extotal + extracharge;
  return {
    Extotal,
    ExclufeeAmount,
    excluService,
    extracharge,
    TotalExclusive,
  };
}

function MyComponent() {
  const [basecurrency, setBaseCurrency] = useState("USD");
  const [totalamount, setTotalAmount] = useState(0);
  const [userDetails, setUserDetails] = useState();
  const [prices, setPrices] = useState();
  const [results, setResults] = useState();

  useEffect(() => {
    // Need an IIFE here since `useEffect` can not return a promise
    (async () => {
      setUserDetails(await getUserDetails());
      setPrices(await getConversionPriceList());
    })();
  }, []);

  useEffect(() => {
    if (!(userDetails && prices)) {
      // Not ready to compute yet
      return;
    }
    setResults({
      inclusive: inclusiveTask(/* ... */),
      exclusive: exclusiveTask(/* ... */),
    });
  }, [prices, userDetails, basecurrency, totalamount]);
  if (results === undefined) {
    return <>Still loading...</>;
  }
  return <>{JSON.stringify(results)}</>;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM