react-native: DatepickerIOS onDateChange reports the wrong date
When using datepickerIOS the onDateChange callback sometimes reports the wrong date. By changing between date and month in quick succession you’ll quickly find that the date reported by onDateChange is different from that shown on the datepicker. It’s worth noting that the callback does fire correctly, it’s just the date it provides is stale.
It’s much easier to replicate on device but still possible on the simulator. Here’s an example of the problem:
The code is straight forward:
class DatePickerBug extends Component {
constructor(props) {
super(props);
this.state = {
date: new Date()
};
}
onDateChange(date) {
this.setState({
date: date
});
}
render() {
return (
<View style={styles.container}>
<Text>{this.state.date.toString()}</Text>
<DatePickerIOS
date={this.state.date}
mode="date"
onDateChange={(date) => this.onDateChange(date)}
/>
</View>
);
}
}
We’ve noticed this issue in both 0.26 and 0.27. It didn’t exist in 0.22 but because we upgraded our project in one move from 0.22 to 0.26 I’m unsure which version introduced the bug.
If anyone would like to get up and running with the example I have it here https://github.com/willmcneilly/RNDatepickerIOSBug
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 45
- Comments: 45 (14 by maintainers)
I had this same issue as well. In the end, what worked for me was to include the
timeZoneOffsetInMinutes
attribute to the DatePickerIOS component:Make sure to multiply timezone offset by -1
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.
This is how I fix it: onDateChange(date){ var _date = new Date(date); _date.setMinutes( _date.getMinutes() - _date.getTimezoneOffset()); this.setState({birthday: _date}); }
Hope it useful!
Hi, I wonder know that whether the RN team notice this bug?
@varungupta85 I’ve released my uncontrolled DatePicker version as a library: https://github.com/dgladkov/react-native-uncontrolled-date-picker-ios
I’ve tried to add
getDate
method to RCTDatePicker and submit a PR, but current implementation aggressively updates date on each change event, so my approach will not work unless I change current behavior.Still a problem in 0.49, how can we let the RN team know about this? It seems to be lost in the endless issue graveyard.
Here’s a link to product pains, in case that makes any difference.
Please vote for it if you want that fixed.
https://react-native.canny.io/feature-requests/p/datepickerios-wrong-date-or-time
Spent past couple of days fighting this bug, according to my findings problem is that action for
UIControlEventValueChanged
does not fire at all in some cases [1], specifically if you turn multiple wheels simultaneously in same direction. This is indeed a bug in iOS itself, not in React Native.I worked around that problem by making a custom native getter method that returns
UIDatePicker
’s date, thus effectively making datepicker uncontrolled. If anyone is interested in this solution, I can make a PR for this.[1] https://github.com/facebook/react-native/blob/master/React/Views/RCTDatePicker.m#L34
The issue is not fixed, the problem still occurs
https://github.com/dgladkov/react-native-uncontrolled-date-picker-ios works great for me. Would be awesome to add this API in the original
DatePickerIOS
API, is there anyway to get this under the attention of the React Native team? This issue has been there for as early as December 2015…I upgraded project from @willmcneilly to latest stable versions of React & React Native. The bug is still there.
“react”: “^16.2.0”, “react-native”: “^0.52.2”
This is still broken. It seems to be a problem on the native side, but I cannot fix the native plugin myself, unfortunately. Someone, please help out.
Update: Did some digging and the date is also wrong (i.e. stuck on the last date) inside
RCTDatePicker.m
(void)didChange
, so the problem is before that function is being invoked.Update 2: As a workaround, I wrapped a
View
around theDatePickerIOS
component to block pointer-events for 500ms after theonDateChange
handler was called. This is not ideal, but prevents the user to see false data.@tomazahlin I have tried to clone the Date object, but didn’t matter =/
@JakeRawr That is why it is so frustrating! It doesn’t happen every time, so you can’t find a reliable solution…
Still having this issue, using range, when logging the dates it logging the right date, but when formatting the date something is going wrong, react native 0.61:(
Although https://github.com/dgladkov/react-native-uncontrolled-date-picker-ios seems to fix this issue, it doesn’t support the
locale
prop, which is needed for a work-around to support 24 hour time, so it’s not really a solution for this issue.Did this commit (https://github.com/facebook/react-native/commit/446ce49) in 0.55 fix this issue?
I was getting intermittent results in the first place, so it’s hard to tell. 🤔
The comment for the new
initialDate
prop says: “The controlled state has known bugs which causes it to go out of sync with native. The initialDate prop is intended to allow you to have native be source of truth.”I’m using the
initialDate
prop now and I haven’t seen the issue yet, but I still need more testing to be sure.For anyone having issues I recommend @dgladkov 's component. Works well for me https://github.com/dgladkov/react-native-uncontrolled-date-picker-ios
If this helps anyone else, you need to check the state of the date within a callback.
@davidpfahler Do you mind sharing the code that you have used to wrap a
View
around the date time picker and block the pointer events?This is what I have right now. Just wanted to make sure I didn’t miss anything
Update May 15, 2017 Users started to complain after I plugged in the above workaround and it is still possible to get false data with the above workaround. One way to get false data even with the above workaround is when the user moves the minutes and when the minutes’ carousel is about to stop just move the hour hand slightly such that it doesn’t change the hour but it does move a little.
It would be great if somebody with native iOS experience could look into it.
@ammichael I have just seen I had a totally another problem, which I solved. My problem was that the DatePickerIOS sometimes gave back a date object where day was 1 to less. I solved it by not doing let date = new Date(year,month,day);, but by doing let date = new Date(); date.setUTCFullYear(year,month,day); Using the provided example on the top it works flawlessly. The date always changes. I also cannot reproduce the problem which you describe, about the previous date being set. Maybe try cloning the Date object before setting it to state? I think if the same object reference is set to state or received by props, the component would not re-render. Just my suggestion what you could try.