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

时间:2020-08-07 06:44:07

标签: javascript reactjs react-hooks use-effect

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

每个状态都有不同的功能,状态改变时会调用它们。
最初,两个状态都设置为0。

挑战
每当加载组件时,由于状态更改,页面会连续重新渲染,并且无法输入任何输入。

 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);
   });
};

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

2 个答案:

答案 0 :(得分:0)

仅需检查一下您的值是否已更改一次,如果更改过,请使用return语句防止循环。另外,您还可以将代码分成两个单独的useEffects,以使其更清晰,更轻松地使用代码。

下面是一些示例:enter image description here

答案 1 :(得分:0)

认为您可能正在寻找这样的表述,但是从如此庞大的问题中很难分辨出来。

这里的想法是

  • getUserDetails返回对用户详细信息的承诺
  • getConversionPriceList返回一个诺言价目表数据(以前在inclusiveTask / exclusiveTask函数中)
  • inclusiveTaskexclusiveTask是只做数学的简单非异步函数

这些都是这样的:

  • 第一个useEffect没有依赖项,即,在安装组件时,它仅运行一次。它调用用户详细信息和价格函数,并将这些位存储在状态中。
  • 第二个useEffect取决于用户详细信息和价目表,以及基本货币和金额的状态(无论如何,我都不知道您的业务逻辑)。它有一个保护措施,使其在加载效果完成之前不做任何事情。
  • 渲染仅显示“正在加载”,直到所需的状态准备就绪,然后毫不客气地将计算结果转储为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)}</>;
}