Как остановить автоматический повторный рендеринг компонентов с помощью хука useEffect? - PullRequest
1 голос
/ 07 августа 2020

Я использую хук useEffect и у меня два состояния. Два состояния зависят друг от друга; это означает, что когда я изменяю одно состояние basecurrency, тогда другое состояние totalamount также обновляется, и наоборот.

Каждое состояние имеет разные функции, которые вызываются при изменении состояний. Первоначально оба состояния установлены как значение 0.

Challenge Всякий раз, когда компонент загружается, страница постоянно обновляется из-за изменений состояния, и я не могу вводить какие-либо данные.

 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 голосов
/ 07 августа 2020

Я думаю, вы, возможно, ищете такую ​​формулировку, но это действительно сложно сказать из такого обширного вопроса.

Идея здесь в том, что

  • getUserDetails возвращает обещание сведений о пользователе
  • getConversionPriceList возвращает обещание данных прайс-листа (которые ранее были в функциях inclusiveTask / exclusiveTask)
  • inclusiveTask и exclusiveTask - это простые неасинхронные c функции, которые просто выполняют математические вычисления

Они подключаются следующим образом:

  • первый useEffect не имеет зависимостей, т.е. он запускается ровно один раз при монтировании компонента. Он вызывает данные пользователя и функции цены и сохраняет эти биты в состоянии.
  • второй useEffect зависит от данных пользователя и прайс-листов, а также от состояния базовой валюты и суммы (независимо от это я не знаю про ваш бизнес логи c). У него есть защита, чтобы он ничего не делал, пока не закончатся эффекты загрузки. sh.
  • Рендеринг просто говорит «Загрузка» до тех пор, пока требуемое состояние не будет готово, а затем он бесцеремонно выгружает результаты вычислений как 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)}</>;
}
0 голосов
/ 07 августа 2020

Просто вам нужно проверить, изменились ли ваши значения один раз, и если это произошло - используйте оператор return для предотвращения зацикливания. Также вы можете разделить свой код на два отдельных useEffects, чтобы упростить работу с кодом.

Вот пример: введите описание изображения здесь

...