Как использовать @ response-native-community/datetimepicker с формой React Hook?

Я пытаюсь сделать средство выбора даты, которое появляется при нажатии на поле со значком и текущей датой в строковом формате.

Я использую React Native, React Hook Form и @response-native-community/datetimepicker.

Случайно я нашел там интересный ответ на несвязанный вопрос: /questions/24761706/reaktivnaya-oshibka-znachenie-dlya-datyi-ne-mozhet-byit-preobrazovano-iz-stroki-v-dvojnuyu/55074483#55074483

Я реализовал это так:

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.

1 ответ

Чтобы использовать@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;

Другие вопросы по тегам