Datetime-local value with React

I am doing my first project with React, and I hit a wall, how to use a local datetime field using normal React logic.

For any given input field, I would do as described in the React documentation .

The problem for me is that the datetime-local field has some annoying return values. It returns an empty string in cases two . One case is when you use the built-in clear button, and in the other case, when an invalid date is set - for example, February 29, 2015.

Since this is the case, I cannot just set the field value to the value of event.target.value, as this will reset the field every time someone clicks on an invalid date. If I tell him to do nothing when I encounter an empty return value, it means that you can no longer use the clear button in the field.

I was not able to find anything related to this problem, so I hope someone has an idea to solve it.

+10
javascript html5 reactjs
source share
4 answers

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

This leads to the fact that the field is not blocked by the state variable, which, in turn, allows me to make the onChange function, which always updates the state, but does not have any effect on the field itself.

Thus, the field behaves as expected, and I can simply send any value to my state.

The disadvantage of this solution is that I cannot confirm the date. This means that if someone tries to send an invalid date, it will simply be stored as zero in the database.

If anyone comes up with a more elegant solution, I would be happy to hear it.

+10
source share

Edit the getDay patch for getDate, as getDay returns the day of the week, and getDate returns the day of the month.

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

Since this is a controlled component, you must set the status value to read. I set the current date and time in this state ...

 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 can be used for other text inputs, like so:

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

Change my change, do not add 1 to the day of the month

Edit in josh answer to fix getDay for getDate, since getDay returns the day of the week and getDate returns the day of the month.

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

Since this is a controlled component, you must set the status value to read. I set the current date and time in this state ...

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

and my handleChange can be reused for other text inputs, like so:

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

The trick to solving this problem is to use the .validity.valid property of the input field (see https://developer.mozilla.org/en-US/docs/Web/API/ValidityState ). If it is false, do not update the state of React. It might 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); } 
0
source share

All Articles