Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyboardController.dismiss() will be causing crash #736

Closed
sp0033212000 opened this issue Dec 18, 2024 · 1 comment
Closed

KeyboardController.dismiss() will be causing crash #736

sp0033212000 opened this issue Dec 18, 2024 · 1 comment
Assignees

Comments

@sp0033212000
Copy link

Describe the bug
The app will crash when the KeyboardController.dismiss() be calling.

Code snippet

import React, { PropsWithChildren, useCallback, useState } from "react";
import { useController } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { View, ViewProps } from "react-native";
import { KeyboardController } from "react-native-keyboard-controller";

import { faCalendar, faChevronRight } from "@fortawesome/pro-regular-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome";
import DateTimePicker, {
  DateTimePickerEvent,
} from "@react-native-community/datetimepicker";
import dayjs from "dayjs";
import { FieldPath, FieldValues } from "react-hook-form/dist/types";
import { UseControllerProps } from "react-hook-form/dist/types/controller";

import Fonts from "@/component/General/Fonts";
import FormField, { FormFieldProps } from "@/component/General/Form/FormField";

import { marginStyle, utilsStyle } from "@styles/utils";
import { color } from "@styles/variable";

import { useCollapse } from "@hooks/useCollapse";
import { useUpdateEffect } from "@hooks/useReact";

type Props = {
  style?: ViewProps["style"];
  label?: string;
  todayIsDefault?: boolean;
  isOptional?: boolean;
  showIcon?: boolean;
};

interface DatePickerComponent extends FCWithoutComponent {
  <
    TFieldValues extends FieldValues = FieldValues,
    TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
  >(
    props: PropsWithChildren<
      UseControllerProps<TFieldValues, TName> &
        Props &
        Pick<FormFieldProps, "theme" | "borderType">
    >,
    context?: any,
  ): ReturnType<React.FC>;
}

const DatePicker: DatePickerComponent = ({
  name,
  rules,
  shouldUnregister,
  defaultValue,
  control,
  disabled,
  label,
  showIcon = false,
  theme,
  isOptional,
  borderType = "outline",
  todayIsDefault = true,
}) => {
  const [date, setDate] = useState<Date>(
    () =>
      new Date(
        new Date().getFullYear() - (todayIsDefault ? 0 : 18),
        new Date().getMonth(),
        new Date().getDate(),
      ),
  );
  const {
    field: { value, onChange },
  } = useController({
    name,
    rules,
    shouldUnregister,
    defaultValue,
    control,
    disabled,
  });
  const { isCollapse, collapse, expand } = useCollapse();
  const { t } = useTranslation();

  useUpdateEffect(() => {
    onChange(dayjs.tz(date.toUTCString(), "Greenwich").toISOString());
  }, [date]);

  const handleChange = useCallback(
    (_: DateTimePickerEvent, selectedDate?: Date) => {
      if (!selectedDate) return;
      collapse();
      setDate(dayjs(selectedDate).startOf("day").toDate());
    },
    [],
  );

  const handleExpand = useCallback(async () => {
    // Keyboard.dismiss();
    // await sleep(100);
    await KeyboardController.dismiss();
    expand();
  }, [expand]);

  return (
    <FormField
      label={label}
      labelPosition={"left"}
      labelIcon={showIcon ? faCalendar : undefined}
      labelWeight={"400"}
      borderType={borderType}
      theme={theme}
      isOptional={isOptional}
      onPress={handleExpand}
    >
      <View style={[utilsStyle.horizonCenter, utilsStyle.justifyEnd]}>
        {value ? (
          <Fonts fontColor={"grey2"}>
            {dayjs(new Date(value)).format("YYYY/MM/DD")}
          </Fonts>
        ) : (
          <Fonts fontColor={"grey2"}>{t("common:pleaseSelect")}</Fonts>
        )}
        <FontAwesomeIcon
          icon={faChevronRight}
          color={color.grey3}
          size={15}
          style={[marginStyle.left.sp8]}
        />
      </View>
      {!isCollapse && (
        <DateTimePicker
          testID={"dateTimePicker"}
          value={new Date(value || date)}
          mode={"date"}
          display={"spinner"}
          onChange={handleChange}
        />
      )}
    </FormField>
  );
};

export default DatePicker;

Repo for reproducing

const App = () => {
  return (
    <KeyboardProvider statusBarTranslucent>
      <View style={[utilsStyle.fullSize, utilsStyle.flexCenter]}>
        <TextInput
          onChangeText={setValue}
          value={value}
          style={{
            borderWidth: 1,
            borderColor: "red",
            width: 100,
            height: 100,
          }}
        />
        <Pressable
          onPress={async () => {
            await KeyboardController.dismiss();
            Alert.alert("Pressed");
          }}
        >
          <Fonts>Press me</Fonts>
        </Pressable>
      </View>
    </KeyboardProvider>
  );
};

To Reproduce
Steps to reproduce the behavior:

  1. Focus the input
  2. Press the button
  3. See error

Expected behavior
Keyboard disappear after pressing the button

Screenshots
image

Smartphone (please complete the following information):

  • Desktop OS: MacOS 15.1.1
  • Device: Pixel 7a
  • OS: Android Version 15
  • RN version: 0.74.5
  • RN architecture: [e.g. old/new or paper/fabric]
  • JS engine: Hermes
  • Library version: 1.15.0

Additional context
Add any other context about the problem here.

@sp0033212000
Copy link
Author

sorry about that, I have to redeploy the development build after I upgrade the lib from 1.13.0 to 1.15.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants