如何将@react-native-community/datetimepicker与React Hook Form一起使用?

问题描述 投票:0回答:1

我尝试制作一个日期选择器,当单击带有图标的字段和字符串格式的当前日期时会出现该选择器。

我使用 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 组件来保存该值。

我想知道是否有更好的方法。我有一些小顾虑:

  • 我将字符串转换为日期,然后转换为字符串,然后在提交时需要将其转换回日期...实际上 .toLocaleDateString 会使提交变得非常复杂。这可能是国际化的一个问题。
  • onTouchStart 不适用于鼠标,仅适用于触摸设备。这可能是 chromebook 的问题。
javascript react-native datetime datepicker react-hook-form
1个回答
0
投票

要将

@react-native-community/datetimepicker
与 React Hook Form 一起使用,你可以这样做:

  1. 创建一个将日期选择器与表单集成的自定义组件。
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);
          }}
        />
      )}
    />
  );
};

  1. 现在,您可以在表单中使用 DatePicker 组件。确保您已使用 useForm 初始化表单。
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;

© www.soinside.com 2019 - 2024. All rights reserved.