Discover the best practices for integrating @react-native-community/datetimepicker with React Hook Form!

I am attempting to create a date picker that appears when a field with an icon and the current date in string format is clicked.

I am using React Native, React Hook Form, and @react-native-community/datetimepicker.

Fortunately, I came across an interesting solution on an unrelated question:

Here is how I implemented it:

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>
  )

This implementation is challenging because the picker is unmounted when the values are submitted, requiring a TextInput component to hold the value.

I am curious if there is a better approach, as I have some concerns:

  • Converting a string to a date, then back to a string, and then back to a date for submission could complicate things, especially for internationalization with .toLocaleDateString.
  • onTouchStart only works with touch devices, not with mice, which could be an issue for Chromebooks.

Answer №1

To implement the

@react-native-community/datetimepicker
with React Hook Form, follow these steps:

  1. Develop a custom component that combines the date picker with your form.
const DatePicker = ({ control, name, value, onChange }) => {
  return (
    <Controller
      control={control}
      name={name}
      defaultValue={value}
      render={({ field: { onChange, value } }) => (
        <DateTimePicker
          value={value || new Date()} // Use a default value if value is not set
          mode="date" // Options include "time" or "datetime" for varying modes
          is24Hour={true}
          display="default"
          onChange={(event, selectedDate) => {
            onChange(selectedDate);
          }}
        />
      )}
    />
  );
};

  1. Now, integrate the DatePicker component into your form. Ensure that you have initialized your form using useForm.
const MyForm = () => {
  const {
    control,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const [selectedDate, setSelectedDate] = useState(null);

  const onSubmit = (data) => {
    // Manage form submission with the selectedDate and other form data
    console.log(data);
  };

  return (
    <View>
      <Text>Choose a Date:</Text>
      <DatePicker control={control} name="date" value={selectedDate} onChange={setSelectedDate} />
      <Button title="Submit" onPress={handleSubmit(onSubmit)} />
    </View>
  );
};

export default MyForm;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Show a condensed version of a lengthy string in a div using React TS

I've been tackling a React component that takes in a lengthy string and a number as props. The goal of the component is to show a truncated version of the string based on the specified number, while also featuring "show more" and "show less" buttons. ...

Trouble parsing JSON in Classic ASP

After receiving a JSON Response from a remote server, everything looks good. I discovered an helpful script for parsing the JSON data and extracting the necessary values. When attempting to pass the variable into JSON.parse(), I encountered an error which ...

Failed to execute test suite in React and Jest framework

While working on updates for our existing project, I encountered an error that is causing some of the tests to fail: FAIL src/components/changelog/__test__/ChangeLogOverView.test.tsx ● Test suite failed to run TypeError: Cannot create property & ...

Arranging numbers in JavaScript lists

empList = [ { "Account": "AAA - 0029", "Available": "$100" }, { "Account": "BBB- 0146", "Available": "200" }, { "Account": "AAA - 1812", "Available": "300"}, { "Account": "CCC- 2019", "Available": "400"}, { "Account" ...

A system similar to Facebook's ajax like feature without any errors, yet producing no visible

I am currently in the process of developing a system similar to Facebook's ajax-like feature. Below is the code I have put together: Jquery function for ajax call: function addLikes(likeid, action) { $('.likebox #tutorial-'+likeid+' ...

Having trouble with Javascript files failing to load while hosting a website on digital ocean?

Recently, I developed a web application using an express backend and the ejs view engine. Everything works perfectly fine when tested on my local machine. However, I encountered issues when trying to host it on a digitalocean droplet (Ubuntu 22.10 x64). Af ...

Tips for invoking the setState method via an onClick event the ES6 way

class BlogPost extends React.Component{ //getInitialState constructor(){ super(); this.onLike = this.onLike.bind(this); this.state = { like :0 } } onLike(){ this.setState({ li ...

ReactJs - SyntaxError: The JSX content is not properly terminated

I'm just starting out with ReactJs and have come across an issue that I can't seem to figure out. Here's my code snippet: var ListComponent = React.createClass({ render: function() { return ( <li>{this.props.va ...

Retrieve the user-inputted data from an Electron BrowserView's input field

Consider this scenario where a BrowserWindow is set up with specific security settings, including enabling the webviewTag: true for project requirements. let webPrefs = { plugins: false, nodeIntegration: false, nodeIntegrationInWorker: false, ...

NestJs Custom Validation Pipe: Exploring the Possibilities with Additional Options

I have created a unique custom validation pipe and I am looking to enhance it with additional custom logic. How can I extend the pipe to allow for the options listed below? After reviewing the Github link provided, I have implemented my own version of the ...

Utilizing TypeDoc to Directly Reference External Library Documentation

I am working on a TypeScript project and using TypeDoc to create documentation. There is an external library in my project that already has its documentation. I want to automatically link the reader to the documentation of this external library without man ...

What is the reason behind observing numerous post requests in the Firebug console after submitting a form through Ajax in jQuery?

I have integrated the jquery Form plugin for form submission and everything seems to be functioning properly. However, upon turning on the firebug console and clicking the submit button, I notice that there are 10 post requests being sent with the same da ...

Tips for maintaining video height consistency while adjusting its attributes

When you click on a button, the video's poster and src attributes change. However, after clicking, the video height briefly becomes 0, causing an unsightly effect on the entire page. How can this be avoided? Please note - lorem.mp4 and ipsum.mp4 hav ...

Interacting with PHP variables in JSON format

I've recently started using JSON to exchange data between pages, but I am facing a challenge that I can't seem to solve. Essentially, my issue lies in one page where I am utilizing jquery's getJSON method to retrieve JSON data from another ...

aligning the last item of the navbar to the right in React Bootstrap

I am attempting to recreate the menu shown in the top image using Bootstrap and React. https://i.sstatic.net/Tv9Tu.png Unfortunately, regardless of the alignment adjustments made, the menu ends up looking like the bottom image instead. https://i.sstatic ...

Steps for retrieving multiple documents from Firestore within a cloud function

In my cloud function, I have set up a trigger that activates on document write. This function is designed to check multiple documents based on the trigger and execute if/else statements accordingly. I have developed a method that retrieves all documents u ...

Incorrect format option selected in the vue-datetime component

I have come across an issue with the vue-datetime plugin where the format option does not seem to be working correctly. Here is the code snippet that demonstrates the problem: <datetime type="date" v-model="formData.testDate" input-class="form-control" ...

What could be causing the 500 response code when making a request to the NextJS API route within the app directory?

Every time I attempt to access my API route, a 500 Internal Server Error code is returned The origin of the request export const fetchSuggestion = async () => { const response = await fetch('/api/getSuggestion', { cache: 'no-store&ap ...

I'm having trouble customizing the appearance of a Tab Panel using the TabsAPI. The panel keeps expanding in strange ways. How can I

Trying to customize the Tabs component from MUI is proving to be a challenge. The main issue I am facing currently is: Whenever I switch between tabs, they appear to expand in size mysteriously. This behavior seems to occur only on tabs with more content ...

Use JavaScript to jumble up each individual letter

Is there a way to scramble words letter by letter instead of the whole word at once in Vue.js? I'm new to Vue.js and struggling to make this change in my code. I'm currently using Vue.js for this task. const sampleText1 = 'インバウント ...