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



我正在尝试进行一些表单验证。我的表单中有两个受控元素:消息文本框和收件人文本框。因此,我有state.message(字符串)和state.recipients(数组)来控制一些文本框(当您在文本框中键入时,这些值state更改)。状态工作正常。也就是说,当我在消息文本框中输入时,state.messages会更新。当我在收件人框中输入时,state.recipients会更新。invalid是用useState钩子定义的,如下所示:

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

我希望invalid.messagesstate.messages为空时true,当state.recipients为空时invalid.recipients为真。这是我的验证代码,我遇到了一些麻烦:

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,
});
}

不过,我的条件有效的。 当收件人文本框为空时,state.recipients.length确实等于0,当邮件文本框为空时,state.message确实''。现在,有趣的是,当表单的两个元素都为空时(即收件人和邮件都是空的),invalid等于

{
recipients: false,
message: true
}

这非常奇怪,因为我没有看到我用来改变状态的逻辑有任何缺陷。更奇怪的部分是,当我翻转此验证逻辑中的 if 语句时(即,我首先检查消息状态,然后检查收件人状态),然后发生相反的情况:状态如下所示:

{
recipients: true,
message: false
}

我不知道为什么会这样,所以你能指出我的逻辑中的缺陷吗?

编辑:文本框的一些事件处理程序代码: 对于消息文本框:onChange={(e) => { setState({ ...state, message: e.target.value }); }}对于收件人文本框(有意覆盖state.recipients中的第一个元素):

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

但是这段代码真的不是问题,因为状态得到了正确处理,并且在应该为空的时候它是空的。

状态更新是异步的,因此当调用setInvalid并使用...invalid添加以前的状态时,两个更新都使用相同的旧状态

换句话说,当调用您粘贴的代码时,要执行的第一个setInvalid在第二个开始执行并使用...invalid拉入状态之前不会完成状态更新

因此,只有messaged才能正确设置。

您可以通过使两个变量单独的状态对象来解决此问题。

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

相关内容

  • 没有找到相关文章

最新更新