简体   繁体   English

表单验证逻辑问题(使用 React useState Hook)

[英]Form Validation Logic Problem ( Using React useState Hook)

I am trying to do some form validation.我正在尝试进行一些表单验证。 I have two controlled elements in my form: a messages textbox and a recipients textbox.我的表单中有两个受控元素:消息文本框和收件人文本框。 So, I have state.message (a string) and state.recipients (an array) which control some textboxes (when you type in the textboxes, these values of state change).所以,我有控制一些文本框的state.message (一个字符串)和state.recipients (一个数组)(当你输入文本框时,这些state的值会发生变化)。 The state is working properly. state 工作正常。 That is, when I type in the messages textbox, state.messages gets updated.也就是说,当我输入消息文本框时, state.messages会更新。 When I type in the recipients box, state.recipients gets updated.当我在收件人框中输入时, state.recipients得到更新。 invalid is defined with the useState hook like so: invalid是用useState钩子定义的,如下所示:

const [invalid, setInvalid] = useState({
  message: false,
  recipients: false,
})

I want invalid.messages to be true when state.messages is empty, and invalid.recipients to be true when state.recipients is empty.state.recipients为空时,我希望invalid.messagestrue ,当state.messages为空时, invalid.recipients为真。 Here is my validation code, which I am having some trouble with:这是我的验证码,我遇到了一些麻烦:

if (state.recipients.length === 0) {
  setInvalid({
    ...invalid,
    recipients: true,
  });
} else {
  setInvalid({
    ...invalid,
    recipients: false,
  });
}

if (state.message === '') {
  setInvalid({
    ...invalid,
    message: true,
  });
} else {
  setInvalid({
    ...invalid,
    message: false,
  });
}

My conditions are working, though.不过,我的条件有效的。 state.recipients.length is indeed equal to 0 when the recipients textbox is empty, and state.message is indeed '' when the message textbox is blank.当收件人文本框为空时, state.recipients.length确实等于0 ,当消息文本框为空时, state.message确实为'' Now, the interesting part is that when both elements of the form are empty (that is, recipients and message are both empty), invalid is equal to现在,有趣的部分是当表单的两个元素都为空(即收件人和消息都为空)时, invalid等于

{
  recipients: false,
  message: true
}

This is extremely weird because I don't see any flaw in the logic I am using to change the state.这非常奇怪,因为我在用于更改 state 的逻辑中没有发现任何缺陷。 The weirder part is that when I flip the if statements in this validation logic (that is, I check the message state first and then the recipients state) then the reverse happens: state looks like:更奇怪的部分是,当我在此验证逻辑中翻转 if 语句(即,我首先检查消息 state然后检查收件人状态)然后发生相反的情况: state 看起来像:

{
  recipients: true,
  message: false
}

I don't know why this is happening, so can you point out the flaw in my logic?我不知道为什么会这样,所以你能指出我的逻辑缺陷吗?

Edit: Some event handler code for the textboxes: For the messages textbox: onChange={(e) => { setState({...state, message: e.target.value }); }}编辑:文本框的一些事件处理程序代码:对于消息文本框: onChange={(e) => { setState({...state, message: e.target.value }); }} onChange={(e) => { setState({...state, message: e.target.value }); }} For the recipients textbox (which intentionally overrides the first element in state.recipients ): onChange={(e) => { setState({...state, message: e.target.value }); }}对于收件人文本框(故意覆盖state.recipients中的第一个元素):

onChange={(e, val) => setState({
  ...state,
  recipients: val,
})}

But this code really isn't the issue, because the state is being handled properly and it is empty when it supposed to be.但是这段代码真的不是问题,因为 state 处理得当,它应该是空的。

State updates are asynchronous, so when call setInvalid and add the previous state using ...invalid , the same old state is being used for both updates. State 更新是异步的,因此当调用setInvalid并使用...invalid添加先前的 state 时,两个更新都使用相同的旧 state

In other words, when the code you pasted is called, the first setInvalid to execute doesn't finish updating the state before the second one starts executing and pulls in the state using ...invalid .换句话说,当您粘贴的代码被调用时,要执行的第一个setInvalid不会在第二个开始执行之前完成更新state 并使用...invalid拉入 state 。

As a result, only messaged gets set properly.结果,只有messaged被正确设置。

You can likely resolve this issue by making both variables separate state objects.您可以通过将两个变量分开 state 对象来解决此问题。

const [invalidRecipiants, setInvalidRecipiants] = useState(true);
const [invalidMessages, setInvalidMessages] = useState(true);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM