【问题标题】:React waiting for setState to finish then call a function反应等待 setState 完成然后调用一个函数
【发布时间】:2022-01-14 19:10:56
【问题描述】:

当我的代码运行时,它使用旧值来表示兴趣,因为它是异步的,如何让 calcMoney 等待状态更新?提前致谢

更新这是整个代码,因为我刚刚开始反应,所以很可能真的搞砸了,究竟应该属于渲染中的内容以及其他地方应该是什么对我来说仍然是一个谜

import React, { useState } from "react";

function InputForm() {
  const [investinit, setInvestinit] = useState("");
  const [deposit, setDeposit] = useState("");
  const [interest, setInterest] = useState("");

  function changeInit(e) {
    setInvestinit(parseInt(e.target.value));
    console.log(e);
    calcMoney();
  }

  function changeDeposit(e) {
    if (e.target.value == "") {
      e.target.value = 0;
    }
    setDeposit(parseInt(e.target.value));
    calcMoney();
  }

  function changeInterest(e) {
    setInterest(parseFloat(e.target.value), () =>
    console.log(e);
  }

  function calcMoney() {
    var bigArr = [
      { totalAmount: investinit, tottalYield: 0, id: 0, totalMonthly: deposit },
    ];
    var monthlyInterest = interest / 1200 + 1;

    for (var i = 1; i < 13; i = i + 1) {
      var newTotal =
        investinit * Math.pow(monthlyInterest, i) +
        deposit * ((Math.pow(monthlyInterest, i) - 1) / (monthlyInterest - 1));
      var totalMonthly = deposit * i;
      var gain = newTotal - (investinit + totalMonthly);

      bigArr.push({
        totalAmount: newTotal,
        id: i,
        tottalYield: gain,
        totalMonthly: totalMonthly,
      });
      console.log(bigArr);
    }
  }

  return (
    <div className="wrapper">
      <div className="form-wrap">
        <form>
          <div className="form-body">
            <div className="form-item">
              <label>Investment Amount $</label>
              <input
                type="number"
                onChange={changeInit}
                value={investinit}
                placeholder="Investment Amount (required)"
                min="0"
                step="100"
                required
              />
            </div>
            <div className="form-item">
              <label>Monthly investment $</label>
              <input
                type="number"
                onChange={changeDeposit}
                value={deposit}
                placeholder="Monthly Deposit (optional)"
                min="0"
                step="100"
              />
            </div>
            <div className="form-item">
              <label>Annual interest %</label>
              <input
                type="number"
                onChange={changeInterest}
                value={interest}
                placeholder="Annual interest (required)"
                min="0"
                step="0.1"
                required
              />
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}
export { InputForm };

【问题讨论】:

  • 很可能应该在渲染函数中调用 calcMoney 并从状态中直接访问 'insterest'。您能否分享更多代码以查看全貌?
  • 我贴出了整个代码
  • 'calcMoney' 函数除了 console.log 什么都不做?
  • 它确实创建得有点低,我只需要知道当时的事件
  • 然后使用“useEffect”从 Phobos 获得第二个答案,并从 changeDeposit 函数中删除 calcMoney 调用,应该没问题 :)

标签: reactjs async-await


【解决方案1】:

setState 函数采用一个可选的回调参数,可用于在状态更改后进行更新:

setInterest(parseFloat(e.target.value), () => {
   calcMoney();
}

或者,您可以使用 useEffect 并观察 'interest' 的值,并在它发生变化时执行计算。

useEffect(() => {
  calcMoney();
}, [interest]);

【讨论】:

  • 用回调进行了尝试,得到了这个警告:来自 useState() 和 useReducer() Hooks 的状态更新不支持第二个回调参数。要在渲染后执行副作用,请在组件主体中使用 useEffect() 声明它。
  • 然后使用useEffect方法,应该可以达到你想要的效果。
【解决方案2】:

对于这个问题,您会发现三个有用的选项:

  1. 您可以做的第一件事是在函数本身中使用 promiseawait 函数。它可能会导致等待,直到异步函数获取数据,然后使用 setState 更新状态。
  2. 第二种方法是使用回调函数。为此,您可以在异步函数中使用它,也可以更改 setState 函数以接受回调函数。以一种在获取(异步)完成后运行 setState 的方式。
  3. 就是利用useEffect等待async函数的输出,当它发生变化时,useEffect会运行一个函数或者调用其他函数。

请注意,Fetch 已经返回了一个 Promise,所以它可能更多 使用它的声音。

【讨论】:

  • codesandbox.io/s/new-project-z7mdp 这是我的解决方案的代码框,问题是所有内容都使用上一步中的值呈现,试试看你会明白我的意思,有没有简单的解决方案那?我
  • @JanDoležel 我已经对您的代码进行了一些更改(分叉),这些更改可以正常工作。代码可能不是您真正需要的,但您可以了解它是如何工作的。不要忘记支持我的评论或作为最佳答案:link
【解决方案3】:

使用内置的 React Context 进行修复,将值作为道具传递给计算器,并使用值提供者包装所有需要数据的组件。

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
  • 你的答案没有回答你原来的问题,所以不应该真正被标记为解决方案。
猜你喜欢
  • 2021-06-20
  • 2020-11-07
  • 2022-11-17
  • 2022-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
相关资源
最近更新 更多