A working example can be found at Codesandbox
React Final Form is a popular Reactjs Plugin for handling forms. On the other hand React DatePicker is another popular ReactJs plugin with almost 5.6M downloads per week.
React Final Form’s form validation works out of the box, for normal fields. However to handle form validation for third party components can be tricky In this example I am going to share an example of React DatePicker field inside React Final Form component where it is validated as a normal React Final Form field.
I will share only the code here. A working example can be found at this Codesandbox
Here starts the code.
import React, { useState } from "react"; import "./styles.css"; import { Form, Field } from "react-final-form"; import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; import { parse, format, isValid, toDate } from "date-fns"; import { enUS } from "date-fns/locale"; const Error = ({ name }) => ( <Field name={name} subscribe={{ touched: true, error: true }} render={({ meta: { touched, error } }) => touched && error ? <span className="error">{error}</span> : null } /> ); const RenderDatePicker = ({ name, input, input: { value, onChange } }) => { let isValidDate = false; let selected = null; if (value) { const parsedDate = parse(value, "P", new Date(), { locale: enUS }); isValidDate = isValid(parsedDate); selected = isValidDate ? toDate(parsedDate) : null; } return ( <DatePicker placeholderText={ value ? format(new Date(value), "MM/dd/yyyy") : "Enter date" } dateFormat="MM/dd/yyyy" selected={selected} // needs to be checked if it is valid date disabledKeyboardNavigation name={name} onChange={(date) => { // On Change, you should use final-form Field Input prop to change the value if (isValid(date)) { input.onChange(format(new Date(date), "MM/dd/yyyy")); } else { input.onChange(null); } }} /> ); }; const required = (value) => (value ? undefined : "Date is required"); export default function App() { const [initialValues] = useState({ start_date: new Date() }); const onSubmit = (values) => { console.log(values); }; const validate = (values) => { let errors = {}; if (!values.name) { errors.name = "Name is required"; } return errors; }; return ( <div className="App"> <h1>React Final Form + React DatePicker</h1> <h2>An Working example of React Final form with read</h2> <Form onSubmit={onSubmit} validate={validate} initialValues={initialValues} > {({ handleSubmit, form, submitting, pristine, values }) => ( <form className="form" onSubmit={handleSubmit}> <Field name="name"> {({ input, meta }) => ( <div className="form__form-group"> <span className="form__form-group-label">Name</span> <div className="form__form-group-field"> <div className="form__form-group-row"> <input type="text" {...input} placeholder="Enter your name" /> {meta.touched && meta.error && ( <span className="error">{meta.error}</span> )} </div> </div> </div> )} </Field> <div className="form__form-group"> <span className="form__form-group-label">Date</span> <div className="form__form-group-field"> <div className="form__form-group-row"> <Field name="start_date" component={RenderDatePicker} validate={required} /> <Error name="start_date" /> </div> </div> </div> <button type="submit" disabled={submitting} className="btn btn-primary btn-sm" color="#ffffff" > Submit </button> </form> )} </Form> </div> ); }