双击提交按钮使功能正常工作

double click in submit button to make a function work

我有两个功能的问题问题是应该点击按钮两次进行更改,应该只点击一次

const addToBalance = (personId) => {
    userInfo.map((user) => (
        user._id === personId ? setUserGetMoney(user.balance) : ''
    ))
    if (userGetMoney !== 0 && parseInt(inputMoney) !== 0 && parseInt(inputMoney) !== null){
        setUserGetMoney(userGetMoney + parseInt(inputMoney))
        console.log(userGetMoney)
    }
}
const removeFromBalance = () => {
    const id = params.id;
    userInfo && userInfo.map((user) => (
        user._id === id ?  setUserRemoveMoney(user.balance) : ''
    ))
    if (userRemoveMoney !== 0 && personId && parseInt(inputMoney) !== 0 && parseInt(inputMoney) !== null){
       setUserRemoveMoney(userRemoveMoney - parseInt(inputMoney))
       console.log(userRemoveMoney)
    }
} 

提交函数

const onSubmitForm = (e) => {
    e.preventDefault();
    addToBalance(personId);
    removeFromBalance();
    if (personId && parseInt(inputMoney) !== 0 && parseInt(inputMoney) !== null){
        postTransactionData();
    }
}
<button type='submit' onClick={(e) => onSubmitForm(e)}>Submit</button>

当我尝试单击提交按钮来执行 addToBalanceremoveFromBalance 这两个函数时,它们不起作用,但是当我再次单击提交按钮时,它起作用了,我想要一个解决方案,所以我只单击一次按钮即可使功能正常工作

视频说明问题:https://drive.google.com/drive/folders/18usf6CXOyaDi4Py_VbEeNYdyE5Sl91-T?usp=sharing

您的问题是您正在设置状态并期望状态更改为 a:同步,并且 b:在该渲染中可用。

有相当多的资源可以准确了解正在发生的事情,但需要注意的重要一点是,函数中的值位于所谓的闭包中,并且它们不会改变......永远不会,它们似乎只是因为 re-rendering re-creates 变量和那些变量将具有新值而发生变化,但根据定义,它们是每次渲染的不同变量。

第一次失败是因为您的 userGetMoney 和 userRemoveMoney 变量可能设置为 0 开始,然后第一次单击按钮导致它们被设置为当前余额。第二次单击按钮会使它们设置为当前余额,然后再次设置为当前余额 +/- inputMoney。如果您在第一个 运行 之后更改用户,您会发现真正疯狂的事情发生了 - 它会根据前一个用户的资金设置新用户的资金。

我对您的建议是只使用您拥有的值并在函数内传递它,而不是为此使用 React State。

const { useState } = React;

function App({ userId }) {
  const [inputMoney, setInputMoney] = useState("");
  const [userInfo, setUserInfo] = useState(() => [
    { _id: 1, balance: 200, name: "bob" },
    { _id: 2, balance: 250, name: "joe" },
    { _id: 3, balance: 300, name: "billy" },
  ]);
  const [sendeeId, setSendeeId] = useState('');

  function postTransactionData({ sender, sendee, money }) {
    const updatedSender = { ...sender, balance: sender.balance - money };
    const updatedSendee = { ...sendee, balance: sendee.balance + money };
    if(updatedSender.balance<0){
      // Don't have enought funds!
      return;
    }
    console.log("transaction:", updatedSender, updatedSendee);
    setUserInfo((prev) =>
      prev.map((user) => {
        if (user._id === sender._id) {
          return updatedSender;
        }
        if (user._id === sendee._id) {
          return updatedSendee;
        }
        return user;
      })
    );
  }

  function getUser(personId) {
    return userInfo.find((user) => user._id === personId);
  }

  const onSubmitForm = (e) => {
    e.preventDefault();
    const sender = getUser(userId);
    const sendee = getUser(sendeeId);
    const money = parseInt(inputMoney,10);
    if (!sender || !sendee || !money || Number.isNaN(money)) {
      //Invalid transaction
      return;
    }
    postTransactionData({ sender, sendee, money });
  };
  return (
    <form onSubmit={onSubmitForm}>
      <input
        name="money"
        type="number"
        value={inputMoney}
        onChange={(e) => setInputMoney(e.target.value)}
      />
      <select value={sendeeId} onChange={(e) => setSendeeId(+e.target.value)}>
        <option value={''}>Unset</option>
        {userInfo.filter(({_id})=>_id!==userId).map((user) => (
          <option key={user._id} value={user._id}>{user.name}</option>
        ))}
      </select>
      <button type="submit">Submit</button>
    </form>
  );
}

ReactDOM.render(<App userId={1} />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"/>