简体   繁体   English

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

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

I am using useEffect hook and I have two states.我正在使用useEffect钩子,我有两种状态。
The two states depend on each other;两种状态相互依赖; which means that when I change one state basecurrency then the other state totalamount also gets updated and visa versa.这意味着当我更改一个basecurrency时,另一个totalamount totalamount 也会更新,反之亦然。

Each state has different functions that are called when states change.每个 state 都有不同的函数,当状态改变时会调用这些函数。
Initially both states are set as value 0.最初,两种状态都设置为值 0。

Challenge挑战
Whenever the component is loaded, the page re-renders continously due to state changes and am not able to enter any input.每当加载组件时,由于 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]);

These are the functions:这些是功能:

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

Please suggest any solution to help me fix this issue.请提出任何解决方案来帮助我解决此问题。

Simply you need to check is your values changed once, and if it was happen - use return statement to prevent looping.只需检查您的值是否更改过一次,如果发生了 - 使用 return 语句来防止循环。 Also you can split your code in two separate useEffects to make it clear and easier to work with the code.您还可以将代码拆分为两个单独的 useEffects,以使代码更清晰、更容易使用。

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

I think you may be looking for a formulation like this, but it's really hard to tell from such a sprawling question.认为您可能正在寻找这样的公式,但是从这样一个庞大的问题中很难分辨。

The idea here is that这里的想法是

  • getUserDetails returns a promise of user details getUserDetails返回用户详细信息的 promise
  • getConversionPriceList returns a promise the price list data (that was previously in the inclusiveTask/exclusiveTask functions) getConversionPriceList返回一个 promise 的价目表数据(以前在 inclusiveTask/exclusiveTask 函数中)
  • inclusiveTask and exclusiveTask are simple non-async functions that just do maths inclusiveTaskexclusiveTask是简单的非异步函数,它们只是做数学运算

These are hooked up like so:这些是这样连接的:

  • the first useEffect has no dependencies, ie it's run exactly once, when the component mounts.第一个useEffect没有依赖关系,即它只运行一次,当组件安装时。 It calls the user details and price functions and stores those bits in the state.它调用用户详细信息和价格函数并将这些位存储在 state 中。
  • the second useEffect is dependent on the user details and price lists, as well as the state for the base currency and amount (whatever those are, I don't know about your business logic).第二个useEffect取决于用户详细信息和价目表,以及基础货币和金额的 state(不管是什么,我不知道你的业务逻辑)。 It has a guard to make it not do anything until the loading effects finish.它有一个守卫让它在加载效果完成之前不做任何事情。
  • The rendering simply says "Loading" until the required state is ready, and then it unceremoniously dumps the computation results as JSON (if any).渲染只是说“正在加载”,直到所需的 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