我正在使用react-hook-form和zod构建一个React Native应用程序来进行表单处理和验证。我的字段之一 sellPrice 应该接受十进制值(例如 123.45)。然而,我面临两个主要问题:
当我输入小数(例如,点)时,它会立即被删除,从而阻止我输入任何小数。 该字段是必填字段并作为数字进行验证,因此我需要确保在提交表单时输入的数字是有效的数字。 这是我当前的设置:
输入
<Controller
control={control}
name="sellingPrice"
render={({ field: { onChange, onBlur, value } }) => (
<Input
label="Selling Price"
placeholder="Enter Selling Price"
value={value !== undefined && value !== null ? value.toString() : ''}
onBlur={onBlur}
onChangeText={text => {
const sanitizedText = text.replace(/[^0-9.]/g, ''); // Remove invalid characters
if (/^\d*\.?\d*$/.test(sanitizedText)) {
onChange(sanitizedText); // Allow typing decimals
}
}}
keyboardType={Platform.OS === 'ios' ? 'decimal-pad' : 'numeric'}
/>
)}
/>
Zod型:
sellingPrice: z
.number({message: 'Selling Price is required'})
.positive('Selling Price must be positive')
.transform(value => parseFloat(value.toFixed(2))), // Optional rounding to 2 decimals
我有以下内容:
<Controller
control={control}
name="sellingPrice"
render={({field: {onChange, onBlur, value}}) => (
<Input
label="Selling Price"
placeholder="Enter Selling Price"
value={value?.toString() || ''} // Convert number to string and handle undefined
onBlur={onBlur}
disabled={isSubmitting}
onChangeText={text => {
// Allow only numbers with up to two decimal places
const sanitizedText = text.replace(/[^0-9.]/g, ''); // Remove invalid characters
if (/^\d*\.?\d{0,2}$/.test(sanitizedText)) {
// Check decimal limit
onChange(sanitizedText);
}
}}
keyboardType={Platform.OS === 'ios' ? 'decimal-pad' : 'numeric'} // Use 'decimal-pad' for iOS
/>
)}
/>
如果它只是一个字符串值,则该方法有效,但使用此解决方案不会提交表单
我尝试运行你的代码(但没有zod) 它似乎工作正常。 (这是屏幕)
我对zod不太熟悉,它似乎没有改变输入,但没有它它也能工作,所以也许问题就在那里。
如果没有,那么它可能位于您未显示的代码中的某个位置。
这是我测试过的代码
import { Platform, Text, TextInput, View } from 'react-native';
import { Controller, useForm } from 'react-hook-form';
const TempScreen = () => {
const { control } = useForm({
mode: 'all',
});
return (
<View style={{ flex: 1, paddingTop: 40 }}>
<Text>Temp Screen</Text>
<Controller
control={control}
name="sellingPrice"
render={({ field: { onChange, onBlur, value } }) => (
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
// label="Selling Price"
placeholder="Enter Selling Price"
value={value?.toString() || ''} // Convert number to string and handle undefined
onBlur={onBlur}
// disabled={isSubmitting}
onChangeText={(text) => {
// Allow only numbers with up to two decimal places
const sanitizedText = text.replaceAll(/[^\d.]/g, ''); // Remove invalid characters
if (/^\d*\.?\d{0,2}$/.test(sanitizedText)) {
// Check decimal limit
onChange(sanitizedText);
}
}}
keyboardType={Platform.OS === 'ios' ? 'decimal-pad' : 'numeric'} // Use 'decimal-pad' for iOS
/>
)}
/>
</View>
);
};
export { TempScreen };