React Form with Date Picker
The native HTML date input is far more capable than developers typically realise. Setting min and max attributes constrains the calendar automatically and prevents invalid selections without any JavaScript validation. For a date range like an event booking form, calculating the end date minimum from the start date selection is a clean, library-free solution.
The challenge
Date handling in forms is error-prone and often requires third-party libraries, but the native date input covers most use cases with the right constraints.
- Setting min=today without hardcoding a date string — it must be dynamic
- Making the end date minimum update whenever the start date changes
- Handling the case where a user clears the start date after setting the end date
- Formatting dates for display (the input stores YYYY-MM-DD but users expect a human-readable format)
Working code example
Here is a complete, self-contained working example you can drop directly into any React project. It uses Tailwind CSS for styling and requires no external dependencies beyond React itself.
import { useState } from 'react';
function todayString() {
return new Date().toISOString().split('T')[0];
}
function formatDate(str) {
if (!str) return '';
const [y, m, d] = str.split('-');
return new Date(+y, +m - 1, +d).toLocaleDateString('en-US', {
weekday: 'short', year: 'numeric', month: 'short', day: 'numeric',
});
}
export default function EventBookingForm() {
const today = todayString();
const [startDate, setStartDate] = useState('');
const [endDate, setEndDate] = useState('');
const [error, setError] = useState('');
const [submitted, setSubmitted] = useState(false);
const handleStart = (e) => {
const val = e.target.value;
setStartDate(val);
if (endDate && endDate < val) setEndDate('');
setError('');
};
const handleEnd = (e) => {
setEndDate(e.target.value);
setError('');
};
const handleSubmit = (e) => {
e.preventDefault();
if (!startDate) { setError('Please select a start date'); return; }
if (!endDate) { setError('Please select an end date'); return; }
if (endDate < startDate) { setError('End date must be on or after the start date'); return; }
setSubmitted(true);
};
if (submitted)
return (
<div className="max-w-sm mx-auto p-6 bg-green-50 rounded-2xl text-green-700">
<p className="font-semibold">Booking confirmed!</p>
<p className="text-sm mt-1">{formatDate(startDate)} → {formatDate(endDate)}</p>
</div>
);
return (
<form onSubmit={handleSubmit} className="max-w-sm mx-auto p-6 bg-white rounded-2xl shadow space-y-4">
<h2 className="text-xl font-bold text-gray-800">Book an Event</h2>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Start Date</label>
<input type="date" value={startDate} onChange={handleStart} min={today}
className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-teal-500" />
{startDate && <p className="text-xs text-gray-400 mt-1">{formatDate(startDate)}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">End Date</label>
<input type="date" value={endDate} onChange={handleEnd}
min={startDate || today}
disabled={!startDate}
className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-teal-500 disabled:opacity-50 disabled:cursor-not-allowed" />
{endDate && <p className="text-xs text-gray-400 mt-1">{formatDate(endDate)}</p>}
</div>
{error && <p className="text-red-500 text-sm">{error}</p>}
<button type="submit"
className="w-full bg-teal-600 text-white font-semibold py-2 rounded-lg hover:bg-teal-700 transition">
Confirm Booking
</button>
</form>
);
}How ReactForm.co helps
ReactForm's visual builder handles all of the above — date picker configuration, validation rules, state management, and responsive layout — without writing a single line of code. Drag fields onto the canvas, configure their properties in the sidebar, and get production-ready React output. You can publish the form and collect responses instantly, or export the JSX to drop into your own codebase.
Build this form visuallyFrequently asked questions
How do I set the minimum date to today in a date input?
Generate today's date as a YYYY-MM-DD string using new Date().toISOString().split("T")[0] and pass it to the min attribute. Do this in a variable or function call — not hardcoded — so it stays accurate. The native date picker will grey out and block all past dates automatically.
How do I build a date range picker without a library?
Use two date inputs. Set the min of the end date input to the current start date value. When the start date changes, check whether the current end date is now before the new start date and clear it if so. This approach covers the valid range constraint without any library.
Should I use the native date input or a library like react-datepicker?
The native date input is the right choice for most forms — it is lightweight, keyboard accessible, and mobile-friendly. Use a library when you need custom UI that matches your design system exactly, a date range selector in a single picker, or time zone handling. Libraries add 20–50KB; make sure the benefit justifies that.
Related topics
Build this form visually — no code needed
ReactForm.co handles date picker fields, validation, conditional logic, and responsive layout automatically. Publish in minutes and collect responses for free.

