双击提交按钮,使一个功能工作



我有两个函数的问题,问题是应该点击两次按钮进行更改,并且应该只点击一次

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:在该渲染中可用。

有相当多的资源可以准确地了解正在发生的事情,但需要注意的是,函数中的值位于所谓的闭包中,它们不会改变。。。然而,它们似乎只是发生了变化,因为重新渲染会重新创建变量,并且这些变量将具有新的值,但根据定义,每次渲染都是不同的变量。

如何解决React Hook关闭问题?

它第一次失败是因为您的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"/>