Value of datetime-local with React

The trick to solving this is to use the .validity.valid property of the input field (see https://developer.mozilla.org/en-US/docs/Web/API/ValidityState). If this is false, don't update the React state. This could look like this:

const [ datetime, setDatetime ] = useState('');

<input type="datetime-local"
  value={(datetime || '').toString().substring(0, 16)}
  onChange={handleChange} />

function handleChange(ev) {
  if (!ev.target['validity'].valid) return;
  const dt= ev.target['value'] + ':00Z';
  setDatetime(dt);
}

Edit to fix getDay to getDate as getDay returns the day of the week, and getDate returns day of the month.

  <input
    type="datetime-local"
    value={this.state.datetime}
    onChange={e => this.handleChange('datetime', e)}
   />

Since its a controlled component you have to set a state value to read from. I set the current datetime in state like so...

state = {
      datetime: `${new Date().getFullYear()}-${`${new Date().getMonth() +
        1}`.padStart(2, 0)}-${`${new Date().getDate() + 1}`.padStart(
        2,
        0
      )}T${`${new Date().getHours()}`.padStart(
        2,
        0
      )}:${`${new Date().getMinutes()}`.padStart(2, 0)}`
  };

and my handleChange is reuable for other text inputs like so :

handleChange = (field, e) => {
    this.setState({ [field]: e.target.value });
  };

I've solved this for now by setting the value using the JSX "defaultValue" attribute instead of "value".

This results in the field not being locked by the state variable which in turn makes it possible for me to make an onChange function that always updates the state but doesn't have any effect on the field itself.

By doing so the field behaves as expected and I can just submit whatever value is currently in my state.

The downside to solving it like this is that I'm not able to validate the date. Which means if someone tries to submit an invalid date it will just be stored as null in the database.

If anyone comes up with a more elegant solution I'd be glad to hear it.