catamphetamine / react-phone-number-input

React component for international phone number input

Home Page:http://catamphetamine.gitlab.io/react-phone-number-input/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Typing fast results to max depth issue

necm1 opened this issue · comments

Hi!

If you start typing to fast, it somehow throws a "maximum depth issue".

app-index.js:35 Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
    at PhoneInput (webpack-internal:///(app-pages-browser)/../../node_modules/.pnpm/react-phone-number-input@3.3.9_react-dom@18.2.0_react@18.2.0/node_modules/react-phone-number-input/modules/PhoneInput.js:113:26)
    at PhoneInput (webpack-internal:///(app-pages-browser)/../../node_modules/.pnpm/react-phone-number-input@3.3.9_react-dom@18.2.0_react@18.2.0/node_modules/react-phone-number-input/modules/PhoneInputBrowser.js:64:30)
    at _c2 (webpack-internal:///(app-pages-browser)/../../packages/ui/src/components/input.tsx:33:11)
    at eval (webpack-internal:///(app-pages-browser)/../../node_modules/.pnpm/@radix-ui+react-slot@1.0.2_@types+react@18.2.55_react@18.2.0/node_modules/@radix-ui/react-slot/dist/index.mjs:42:23)
    at eval (webpack-internal:///(app-pages-browser)/../../node_modules/.pnpm/@radix-ui+react-slot@1.0.2_@types+react@18.2.55_react@18.2.0/node_modules/@radix-ui/react-slot/dist/index.mjs:16:23)
    at eval (webpack-internal:///(app-pages-browser)/../../packages/ui/src/components/form.tsx:124:14)
    at div
    at eval (webpack-internal:///(app-pages-browser)/../../packages/ui/src/components/form.tsx:74:11)
    at Controller (webpack-internal:///(app-pages-browser)/../../node_modules/.pnpm/react-hook-form@7.51.1_react@18.2.0/node_modules/react-hook-form/dist/index.esm.mjs:544:18)

Input.tsx:

import RPNInput, {
  PropsWithoutSmartCaret as RPNIProps,
  isValidPhoneNumber,
  isPossiblePhoneNumber,
} from 'react-phone-number-input/input';

const PhoneInput: React.ForwardRefExoticComponent<
  RPNIProps<React.InputHTMLAttributes<HTMLInputElement>>
> = React.forwardRef<
  React.ElementRef<typeof RPNInput>,
  RPNIProps<React.InputHTMLAttributes<HTMLInputElement>>
>(({ className, ...props }, ref) => {
  return (
    <RPNInput
      ref={ref}
      className={cn(className)}
      country="DE"
      international
      withCountryCallingCode
      useNationalFormatForDefaultCountryValue
      inputComponent={Input}
      {...props}
    />
  );
});
PhoneInput.displayName = 'PhoneInput';

Component.tsx:

            <FormField
              control={form.control}
              name="phoneNumber"
              render={({ field }) => (
                <FormItem className="flex flex-col flex-1">
                  <FormLabel>Telefonnummer</FormLabel>
                  <FormControl>
                    <PhoneInput {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
              rules={{
                required: 'Bitte geben Sie Ihre Telefonnummer ein.',
                validate: (value) => {
                  if (!value) {return true;}

                  console.log('test');

                  return (
                    isValidPhoneNumber(value, {
                      defaultCountry: 'DE',
                    }) || 'Bitte geben Sie eine gültige Telefonnummer ein.'
                  );
                },
              }}
            />

I thought it's due to my "validate" rule, but console.log never gets triggered. Just wondering.

When I type slowly, it seems to be working - anyway this shouldn't be the case if I start typing too fast or vice versa.

Regardless of you code, if the issue was reproducible on the demo page it could be considered a proper bug report but unless it isn’t, it isn’t.

Same error.
Next.js: 14.02
React hook form: 7.51.2

I resolve this problem using use-debounce react library: https://www.npmjs.com/package/use-debounce

I put the onChange function inside a useDebounceCallback, here's an example.

const handleChange = (value) => {
    //handleChangeFunction
  };

const debouncedHandleCellphoneChange = useDebouncedCallback(
    (value) => {
      handleCellphoneChange(value);
    },
    1
  );

<PhoneInput
  country={country}
  value={value}
  onChange={debouncedHandleCellphoneChange}
  placeholder={placeholder}
/>

same issue with react-hook-form. I tried debounce for onChange handler but it doesn't work.

import React from "react";
import { useDebouncedCallback } from "use-debounce";

import { cn } from "@acme/ui";
import { PhoneInput } from "react-phone-number-input/react-hook-form-input";

interface PhoneInputWrapperProps {
  name: string;
  placeholder?: string;
  required?: boolean;
  className?: string;
  onChange: (value: string) => void;
  defaultValue: string;
}

const PhoneInputWrapper: React.FC<PhoneInputWrapperProps> = ({
  name,
  placeholder,
  required,
  className,
  onChange,
  defaultValue,
}) => {
  const handleChange = useDebouncedCallback((value: string) => {
    onChange(value);
  }, 1);

  return (
    <PhoneInput
      country="JP"
      name={name}
      required={required}
      className={cn(
        "h-full rounded-md border-none bg-gray-100 px-3 py-4 text-lg placeholder:text-neutral-400 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
        className,
      )}
      placeholder={placeholder}
      onChange={handleChange}
      defaultValue={defaultValue}
    />
  );
};

export default PhoneInputWrapper;

it seems onChange property of PhoneInput does not override onChange Event. Without onChange, it works when normally typing.

Any ideas?

same issue with react-hook-form. I tried debounce for onChange handler but it doesn't work.

import React from "react";
import { useDebouncedCallback } from "use-debounce";

import { cn } from "@acme/ui";
import { PhoneInput } from "react-phone-number-input/react-hook-form-input";

interface PhoneInputWrapperProps {
  name: string;
  placeholder?: string;
  required?: boolean;
  className?: string;
  onChange: (value: string) => void;
  defaultValue: string;
}

const PhoneInputWrapper: React.FC<PhoneInputWrapperProps> = ({
  name,
  placeholder,
  required,
  className,
  onChange,
  defaultValue,
}) => {
  const handleChange = useDebouncedCallback((value: string) => {
    onChange(value);
  }, 1);

  return (
    <PhoneInput
      country="JP"
      name={name}
      required={required}
      className={cn(
        "h-full rounded-md border-none bg-gray-100 px-3 py-4 text-lg placeholder:text-neutral-400 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
        className,
      )}
      placeholder={placeholder}
      onChange={handleChange}
      defaultValue={defaultValue}
    />
  );
};

export default PhoneInputWrapper;

it seems onChange property of PhoneInput does not override onChange Event. Without onChange, it works when normally typing.

Any ideas?

Did you try to increase the delay of debouncedCallback?