Datetimepicker: Time picker sometimes resets value to previous value after change

Created on 11 Jun 2020  路  14Comments  路  Source: react-native-datetimepicker/datetimepicker

Bug report

馃憢 Hello!

Summary

When using the Time mode, the value seems to jump to a previously selected value. I am using the iOS Simulator and have not been able to test it on a real device yet.

Environment info

System:
    OS: macOS 10.15.5
    CPU: (16) x64 AMD Ryzen 7 1700X Eight-Core Processor         
    Memory: 1.32 GB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.18.0 - ~/.nvm/versions/node/v12.18.0/bin/node
    Yarn: 1.22.4 - ~/.nvm/versions/node/v12.18.0/bin/yarn
    npm: 6.14.4 - ~/.nvm/versions/node/v12.18.0/bin/npm
  SDKs:
    iOS SDK:
      Platforms: iOS 13.5, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
  IDEs:
    Xcode: 11.5/11E608c - /usr/bin/xcodebuild
  npmPackages:
    react: ~16.9.0 => 16.9.0 
    react-native: https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz => 0.61.4

Library version: 2.2.2

Steps to reproduce

  • Use DateTimePickerModal with mode="time"
  • Change minute value to say 25
  • Change it to say 50
  • Every now and then the time picker will reset the minute value to 25

Reproducible sample code

I have videos, but they are not very clear since they do not the pointer intent very well, it looks like I could just be dragging down again. I'll work on providing more info.

Code used

const TimePicker = () => {
    const [isDatePickerVisible, setDatePickerVisibility] = useState(false)
    const [time] = useState(() => new Date())

    const showDatePicker = () => {
        setDatePickerVisibility(true)
    }

    const hideDatePicker = () => {
        setDatePickerVisibility(false)
    }

    const handleConfirm = (date: Date) => {
        hideDatePicker()
        console.log('date is', date)
    }

    return (
        <>
            <Button onPress={showDatePicker} title="Show date" />
            <DateTimePickerModal
                isVisible={isDatePickerVisible}
                testID="dateTimePicker"
                date={time}
                mode="time"
                onConfirm={handleConfirm}
                onCancel={hideDatePicker}
            />
        </>
    )
}
bug released

Most helpful comment

Same issue, experiencing in "time" mode. Pasting below a gif to demonstrate - I am changing the hour from 00 to 03 as expected and then trying to change the minute from 00 to 58, where when I release my mouse (or finger when testing on a real device) it snaps back to the previous value.

The issue only seems to happen when I change a value shortly after a previous change, before it has had a chance to "settle in". Help would be much appreciated!

2020-06-30 10 16 35

All 14 comments

We're experienced this exact issue with a "date" only picker.

Also experiencing this issue with "time" mode

Same issue, experiencing in "time" mode. Pasting below a gif to demonstrate - I am changing the hour from 00 to 03 as expected and then trying to change the minute from 00 to 58, where when I release my mouse (or finger when testing on a real device) it snaps back to the previous value.

The issue only seems to happen when I change a value shortly after a previous change, before it has had a chance to "settle in". Help would be much appreciated!

2020-06-30 10 16 35

Looks exactly like my issue. Has anyone been able to reproduce this on a real device? So not on the simulator? 馃

I have it also on my physical iOS devices in both development and production.

This happens on my real device.

Have people here tried wrapping it in useMemo like mentioned in this comment on issue #182?

Apparently some have had this issue because their component rerenders while you're in the datetimepicker, which causes it to reset to default due to the original props getting passed in again.

Hi -

We were also struggling with timezone related "date jumping" issues. Specifically, we had two issues:

  1. during selection in the picker, sometimes the date would jump back one
  2. after selection and clicking done, the date would change to back one

Because the DateTimePicker requires to receive the date in Date format, but our app generally deals with and stores the date as a string, our working assumption was that a lot of these issues were related to converting between strings and javascript Date(), and timezone related issues cropping up in the process.

In our original code, we wrote custom code to inject timezone into the string and pass to Date(). After a long struggle bus of debugging, we found this helpful article which led us to the fix: https://medium.com/@lefloh/react-native-and-the-jumping-datepicker-853070554fb4

Root cause - essentially it seems that the timezone handling within React Native's javascript core is unreliable (so doing things like new Date().getTimezoneOffset()) were producing unreliable results.

The fix - use moment js to injectTimezone if you have to convert between date strings and date objects. To give you a sense, in the end some key code in our component looks like this:

// This will format your date into a string e.g. "2020-08-11"
const getFormattedDate = (selectedDate) => {
    return `${selectedDate.getFullYear()}-${padDateValue(
        selectedDate.getMonth() + 1,
    )}-${padDateValue(selectedDate.getDate())}`;
};

// This will inject the current timezone into your dateString and return a date
const injectTimezone = (dateString) => {
    return moment.tz(dateString, moment.tz.guess()).toDate();
};

Hope this is helpful!

Have people here tried wrapping it in useMemo like mentioned in this comment on issue #182?

Apparently some have had this issue because their component rerenders while you're in the datetimepicker, which causes it to reset to default due to the original props getting passed in again.

Have just tried to fix this issue using useMemo - no luck unfortunately

The issue #68 is also related to this.

I suggest test with the DatePickerIOS from react-native if the problem persist, let me know

:tada: This issue has been resolved in version 2.6.1 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

Hey guys. I'm facing the problem in version @3.0.1. I'm fixing it temporarily (i hope) with a dumb solution.

const showMode = (currentMode) => {
setShow(true);
setShow(false); //As It's a re-render problem I set it 'false' to not trigger again.
setMode(currentMode);
};

馃帀 This issue has been resolved in version 2.6.1 馃帀

The release is available on:

Your semantic-release bot 馃摝馃殌

I am using 2.6.1 and it is still having the issue....

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ctohster picture ctohster  路  3Comments

corradio picture corradio  路  5Comments

gabrieljablonski picture gabrieljablonski  路  5Comments

sorinsi picture sorinsi  路  5Comments

otaviogaiao picture otaviogaiao  路  5Comments