Nim*_*ima 5 javascript forms reactjs react-native react-hook-form
在我的反应应用程序中,我在一页上有两个地址表单,它们有两个保存地址函数,可将地址保存在数据库中。还有一个提交按钮,可以提交两个字段并导航到下一页(圆圈中的加号按钮将地址添加到已保存的地址列表中):
我想要做的是验证表单字段,并且我已经通过调用挂钩的两个实例来做到这一点useForm():
// useForm hook
const {
control: senderControl,
handleSubmit: handleSenderSubmit,
setValue: senderSetValue,
} = useForm({
defaultValues: {
senderName: '',
senderLastName: '',
senderPostalCode: '',
senderPhone: '',
senderAddress: '',
},
});
// useForm hook
const {
control: receiverControl,
handleSubmit: handleReceiverSubmit,
setValue: receiverSetValue,
} = useForm({
defaultValues: {
receiverName: '',
receiverLastName: '',
receiverPhone: '',
receiverPostalCode: '',
receiverAddress: '',
},
});
Run Code Online (Sandbox Code Playgroud)
然后,我将这两个钩子的 handleSubmit 方法分别添加到每个字段的加号按钮的onClick (onPress在 RN 中)。
这确实单独验证了表单,但是当我尝试使用“提交”按钮提交整个页面时,问题就出现了。
我仍然希望在按下常规“提交”按钮时能够验证这两个地址字段,但我不知道如何用一个实例验证这两个实例handleSubmit并获取return data两个字段的值。
编辑(CustomInput.js):
const CustomInput = ({
control,
name,
rules = {},
placeholder,
secureTextEntry,
keyboardType,
maxLength,
textContentType,
customStyle,
}) => (
<Controller
control={control}
name={name}
rules={rules}
render={({field: {onChange, onBlur, value}, fieldState: {error}}) => (
<View style={customStyle || styles.container}>
<TextInput
value={value}
onBlur={onBlur}
onChangeText={onChange}
placeholder={placeholder}
keyboardType={keyboardType}
maxLength={maxLength}
textContentType={textContentType}
secureTextEntry={secureTextEntry}
style={[
styles.textInput,
{
borderColor: !error
? GENERAL_COLORS.inputBorder
: GENERAL_COLORS.error,
},
]}
/>
{error && <Text style={styles.errMsg}>{error.message || 'error'}</Text>}
</View>
)}
/>
);
Run Code Online (Sandbox Code Playgroud)
用法:
<CustomInput
control={control}
name="senderPostalCode"
rules={{
required: 'Postal Code is Required',
}}
placeholder="Postal Code"
keyboardType="number-pad"
textContentType="postalCode"
customStyle={{
width: '49%',
marginBottom: hp(1),
}}
/>
Run Code Online (Sandbox Code Playgroud)
有什么办法可以做到这一点吗?
感谢@TalgatSaribayev 的评论引导我找到了这个解决方案。
我不需要为地址字段设置任何特定的验证规则,最后我将发送者和接收者表单分成两个不同的页面。
首先,我必须指出,我没有使用APIpostalCode获取和address字段的输入值,而是使用挂钩来获取最新的值。getValues useWatch
// Watch inputs
const watchedInputs = useWatch({
control,
name: ['senderPostalCode', 'senderAddress'],
});
Run Code Online (Sandbox Code Playgroud)
当我将输入值保存getValues在变量中时,我得到了前一个状态而不是最新的状态,解决这个问题的唯一方法是getValues('INPUT_NAME')每当我想获取最新的状态时调用。即使如此,我也需要调用 的实例useWatch而不将其保存在任何变量中以跟踪更改,因为在输入字段中键入根本不会更新getValues。所以最后我决定使用useWatch它的值并将其存储在变量中,并使用它来访问输入字段的值。
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
正如@TalgatSaribayev 指出的那样,仅创建一个useForm实例就足够了。我所要做的就是创建一个函数,该函数将手动设置错误并在按下保存地址按钮时检查其验证。
// Check if sender postal code input has error
const senderHasError = () => {
if (!/^\d+$/.test(watchedInputs[0])) {
setError('senderPostalCode', {
type: 'pattern',
message: 'Postal Code must be a number',
});
return true;
}
// Any other rules
if (YOUR_OWN_RULE) {
setError('senderPostalCode', {
type: 'custom',
message: 'CUSTOM_MESSAGE',
});
return true;
}
// Clear error and return false
clearErrors('senderPostalCode');
return false;
};
Run Code Online (Sandbox Code Playgroud)
问题是,即使错误通过了验证,也不会被更新(清除)。就好像无效的输入不会附加onChange事件侦听器来重新验证它一样。onSubmit当您以模式提交表单时,默认会发生一些情况useForm。(https://react-hook-form.com/api/useform)
所以我决定使用trigger API来手动触发表单验证并在按下保存地址按钮时useForm监听字段上的更改。postalCode
首先,我创建了一个切换状态来更改触发状态:
// Postal code onSubmit event state
const [triggered, setTriggered] = useState(false);
Run Code Online (Sandbox Code Playgroud)
然后使用in atrigger的 API仅当状态设置为 true 并且输入字段的值已更改时才触发输入验证:useFormuseMemotriggered
// Manually trigger input validation if postal code's onSubmit event is true
useMemo(() => {
if (triggered) trigger('senderPostalCode');
}, [watchedInputs[0]]);
Run Code Online (Sandbox Code Playgroud)
我假设我使用 API 触发输入字段的方式与的模式在幕后的工作trigger方式相同:当用户通过使用 更改状态按下保存地址按钮时启动触发器。useFormonSubmittriggersetTrigger
// Add address to sender favorites
const handleAddSenderFavAddress = () => {
// Trigger on the press event
setTriggered(true);
// Return if sender postal code input has error
if (senderHasError()) return;
// SAVE ADDRESS LOGIC
///////////////////////////////
};
Run Code Online (Sandbox Code Playgroud)
useForm除了使用shandleSubmit 函数进行的一般验证之外,这是我设法验证单独输入字段的唯一方法。
我欢迎更多可能带来更好解决方案的答案。
| 归档时间: |
|
| 查看次数: |
5890 次 |
| 最近记录: |