我尝试制作一个日期选择器,当单击带有图标的字段和字符串格式的当前日期时会出现该选择器。
我使用 React Native、React Hook Form 和 @react-native-community/datetimepicker。
偶然我在一个不相关的问题上找到了一个有趣的答案: https://stackoverflow.com/a/61929764/9927519
我是这样实现的:
const MyComponent = () => {
const { userData } = useContext(UserDataContext)
const [isPickerOpen, setIsPickerOpen] = useState(false)
const parsedBirthday = (userData && userData.birthday && userData.birthday.toDate()) || new Date()
const [birthday, setBirthday] = useState(parsedBirthday)
// Validation schema
const schema = yup.object({
birthday: yup.date(),
})
const { control, handleSubmit, errors } = useForm({resolver: yupResolver(schema)})
const onSubmit = async (data: any) => {
console.log(data)
}
const datePickerHandler = (selectedDate: Date) => {
const currentDate = selectedDate || birthday
if (Platform.OS === 'android') setIsPickerOpen(false)
setBirthday(currentDate)
}
const showDatePicker = () => {
setIsPickerOpen(true)
}
return (
<View style={styles.fieldContainer}>
<Text style={styles.helper}>Birthday</Text>
<TouchableHighlight activeOpacity={0.6} underlayColor="#DDDDDD" onPress={showDatePicker} style={styles.birthday}>
<>
<Icon name="calendar-edit" size={32} color={colors.black} />
<Controller
control={control}
render={({ onChange, onBlur, value }) => (
<TextInput
style={styles.birthdayText}
value={birthday.toLocaleDateString()}
editable={false}
pointerEvents="none"
onTouchStart={() => showDatePicker()}
/>
)}
name="birthdayString"
defaultValue={birthday.toLocaleDateString() || new Date().toLocaleDateString()}
/>
</>
</TouchableHighlight>
{/* Date picker */}
{isPickerOpen && (
<Controller
control={control}
render={({ onChange, onBlur, value }) => (
<>
<View>
<DateTimePicker
minimumDate={new Date(1901, 0, 1)}
maximumDate={new Date()}
value={value}
mode="date"
display="default"
onChange={(event, value) => {
datePickerHandler(value)
}}
/>
</View>
</>
)}
name="birthday"
defaultValue={birthday}
/>
)}
<Text style={styles.errorText}>{errors?.birthday}</Text>
</View>
)
这个有点难,因为提交值时选择器被卸载。然后,我们需要一个 TextInput 组件来保存该值。
我想知道是否有更好的方法。我有一些小顾虑:
要将
@react-native-community/datetimepicker
与 React Hook Form 一起使用,你可以这样做:
const DatePicker = ({ control, name, value, onChange }) => {
return (
<Controller
control={control}
name={name}
defaultValue={value}
render={({ field: { onChange, value } }) => (
<DateTimePicker
value={value || new Date()} // Provide a default value if value is empty
mode="date" // You can use "time" or "datetime" for different modes
is24Hour={true}
display="default"
onChange={(event, selectedDate) => {
onChange(selectedDate);
}}
/>
)}
/>
);
};
const MyForm = () => {
const {
control,
handleSubmit,
formState: { errors },
} = useForm();
const [selectedDate, setSelectedDate] = useState(null);
const onSubmit = (data) => {
// Handle form submission with the selectedDate and other form data
console.log(data);
};
return (
<View>
<Text>Select a Date:</Text>
<DatePicker control={control} name="date" value={selectedDate} onChange={setSelectedDate} />
<Button title="Submit" onPress={handleSubmit(onSubmit)} />
</View>
);
};
export default MyForm;