簡體   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