arqex / react-datetime

A lightweight but complete datetime picker react component.
2k stars 870 forks source link

Cannot reset value #760

Open michalzubkowicz opened 3 years ago

michalzubkowicz commented 3 years ago

I'm Submitting a ...

[X ] Bug report
[ ] Feature request
[ ] Support request

Steps to Reproduce

export const RangeDateTimePicker: FunctionComponent<RangeDateTimePickerProps> = observer((props) => {
    const [firstTimeSeenFromValue, setFirstTimeSeenFrom] = useState('');
    return <div>
        <button onClick={() => setFirstTimeSeenFrom('')}>Reset</button>
        <div>
            <Datetime
                closeOnSelect={true}
                value={firstTimeSeenFromValue}
                onChange={(v => setFirstTimeSeenFrom(v as any))}
            />
        </div>

Expected Results

Value should be empty

Actual Results

Nothing happens

ganz14 commented 3 years ago

@michalzubkowicz do u able to find some work around ? facing same issue

michalzubkowicz commented 3 years ago

@ganz14, Quick and dirty - add key property <Datetime key={'nameofpicker' + value?.getDate}

Where value is value of datepicker from state. It will completely rerender component on date change.

emjoseph commented 3 years ago

Facing the same issue as well.

naeem-gitonga commented 3 years ago

@michalzubkowicz what is the 'nameofpicker'? I tried using a ref, a "name" property, nothing seemed to work, even using what you posted 'nameofpicker ...'

fluent123 commented 3 years ago

I had the same issue. It happens when value in <Datetime> component is changed but you try to reset it and put the same value in setState, so state is not changed and render is not called. The solution is to do force update this.forceupdate(). @emjoseph @JNaeemGitonga

obrejla commented 3 years ago

Hi, same here...it's really annoying. It can render empty value on at first render, then in case of empty value, it just realizes that it's not a truthy value and uses last selected value instead.

ad

I had the same issue. It happens when value in <Datetime> component is changed but you try to reset it and put the same value in setState, so state is not changed and render is not called. The solution is to do force update this.forceupdate(). @emjoseph @JNaeemGitonga

This is not the case... We are having some valid datetime value in the picker and trying to reset it with empty value so the picker is empty.

The problem is that getInputValue() https://github.com/arqex/react-datetime/blob/7e30d6c20cd864bf8e91bc94e6c3a0ee02864d19/src/DateTime.js#L522 calls getSelectedDate() https://github.com/arqex/react-datetime/blob/7e30d6c20cd864bf8e91bc94e6c3a0ee02864d19/src/DateTime.js#L499 which tries to parseDate https://github.com/arqex/react-datetime/blob/7e30d6c20cd864bf8e91bc94e6c3a0ee02864d19/src/DateTime.js#L501 from the props (i.e. our empty string)...it fallbacks to undefined, because empty string is not truthy and because of that getSelectedDate() returns false...and because of false selected value, then getInputValue() fallbacks to this.state.inputValue https://github.com/arqex/react-datetime/blob/7e30d6c20cd864bf8e91bc94e6c3a0ee02864d19/src/DateTime.js#L524 which returns current value 🤷‍♂️

And, yes...workaround with key={value} works...but... 🤷‍♂️

obrejla commented 3 years ago

Btw another possible workaround is to set state.inputValue to empty string in custom reset function, via ref, i.e. something like:

const [value, setValue] = useState('');
const dateInputElement = useRef(null);
...
const myResetFunction = () => {
    dateInputElement.current.state.inputValue = '';
    setValue('');
};
...
<Datetime
    ref={dateInputElement}
    value={value}
/>
haddadnj commented 2 years ago

+1 on this

mgedmin commented 2 years ago

I didn't like either of the two proposed workarounds, so I came up with a third one:


const datetimeWorkaround = (value) => value === '' ? { value: '' } : {};
...
<Datetime
    value={value}
    inputProps={{
       ...datetimeWorkaround(value),
   }}
 />

Setting inputProps.value overrides whatever DateTime.getInputValue() returns. We want to override only in the erroneous case, otherwise Bad Things happen (e.g. typing breaks as it tries to parse incomplete text as datetimes).

Salman-Kashfy commented 1 year ago

@ganz14, Quick and dirty - add key property <Datetime key={'nameofpicker' + value?.getDate}

Where value is value of datepicker from state. It will completely rerender component on date change.

Your a life saver.