gusparis / react-native-month-year-picker

React Native Month Picker component for iOS & Android
MIT License
105 stars 73 forks source link

Android: Method addObserver must be called on the main thread #89

Closed andreyboberskiy-dev closed 2 years ago

andreyboberskiy-dev commented 2 years ago

image

Component code:

`import React, {memo, useCallback, useMemo, useRef, useState} from 'react'; import format from 'date-fns/format'; import MonthPicker, {ACTION_DATE_SET} from 'react-native-month-year-picker'; import {Platform} from 'react-native';

import {Container, Modal, PaymentTextField} from './styles';

function emptyFun() {}

// Interface interface IDatePickerFieldProps { input: {value: string; onChange: () => void}; meta: any; }

const DatePickerField = memo( ({input, meta, ...props}) => { const textFieldRef = useRef(true);

const [pickerOpen, setPickerOpen] = useState(false);

const handleClosePicker = useCallback(() => {
  setPickerOpen(false);
}, []);
const handleOpenPicker = useCallback(() => {
  setPickerOpen(true);
}, []);

const onValueChange = useCallback(
  (event, newDate) => {
    switch (event) {
      case ACTION_DATE_SET:
        input.onChange(newDate);
        break;

      default:
        handleClosePicker();
    }
    handleClosePicker();
  },
  [input, handleClosePicker],
);

const inputForTextField = useMemo(
  () => ({
    ...input,
    onFocus: () => {
      handleOpenPicker();
      textFieldRef.current?.blur();
    },
    value: input.value ? format(input.value, 'MM/yy') : '',
    onChange: emptyFun,
  }),
  [textFieldRef, input, handleOpenPicker],
);

const currentDate = useMemo(() => new Date(), []);

return (
  <>
    <PaymentTextField
      input={inputForTextField}
      meta={meta}
      forwardRef={textFieldRef}
      {...props}
    />
    {Platform.OS === 'android' ? (
      pickerOpen && (
        <MonthPicker
          onChange={onValueChange}
          value={input.value || currentDate}
          minimumDate={new Date()}
          locale="en"
        />
      )
    ) : (
      <Modal
        isVisible={pickerOpen}
        onBackButtonPress={handleClosePicker}
        onBackdropPress={handleClosePicker}
        backdropOpacity={0}
        backdropTransitionOutTiming={0}
        animationInTiming={300}
        animationOutTiming={300}
        coverScreen
        animationOut="slideOutDown"
        isSwipeable={false}
        {...props}>
        <Container>
          <MonthPicker
            onChange={onValueChange}
            value={input.value || currentDate}
            minimumDate={currentDate}
            locale="en"
            mode="number"
          />
        </Container>

      </Modal>
    )}
  </>
);

}, );

export {DatePickerField}; `