hoaphantn7604/react-native-element-dropdown

Getting Maximum Depth Exceeded Warning when using it

anu1097 opened this issue · 3 comments

Here's my component -

import React, { memo, ReactElement, useEffect, useState } from 'react';
import { StyleSheet } from 'react-native';
import { Dropdown } from 'react-native-element-dropdown';

interface InputWithDropdownProps {
  field: string;
  icon: ReactElement<any, any>;
  values: { label: string; value: string }[];
}

const InputWithDropdown = memo(({ field, icon, values }: InputWithDropdownProps) => {
  const [value, setValue] = useState<string | null>(null);
  const [isFocus, setIsFocus] = useState(false);
  // Debug to see re-renders
  useEffect(() => {
    console.log('Value or Focus changed: ', { value, isFocus });
  }, [value, isFocus]);

  const handleFocus = () => {
    if (!isFocus) {
      setIsFocus(true); // Ensure this only triggers once
    }
  };

  const handleBlur = () => {
    if (isFocus) {
      setIsFocus(false); // Ensure this only triggers once
    }
  };

  const handleChange = (item: { value: React.SetStateAction<string | null> }) => {
    if (value !== item.value) {
      setValue(item.value); // Avoid redundant state updates
      setIsFocus(false); // Collapse dropdown
    }
  };

  return (
    <Dropdown
      style={[styles.dropdown, isFocus && { borderColor: 'blue' }]}
      placeholderStyle={styles.placeholderStyle}
      selectedTextStyle={styles.selectedTextStyle}
      inputSearchStyle={styles.inputSearchStyle}
      iconStyle={styles.iconStyle}
      data={values}
      search
      maxHeight={300}
      labelField="label"
      valueField="value"
      placeholder={field}
      searchPlaceholder="Search..."
      value={value}
      onFocus={handleFocus}
      onBlur={handleBlur}
      onChange={handleChange}
      onChangeText={(text) => {
        if (text !== '') {
          setValue(text);
        }
      }}
      renderLeftIcon={() => icon}
    />
  );
});

export default InputWithDropdown;

const styles = StyleSheet.create({
  dropdown: {
    flex: 1,
    borderColor: 'gray',
    borderWidth: 0.5,
    borderRadius: 8,
    paddingHorizontal: 2,
  },
  label: {
    position: 'absolute',
    backgroundColor: 'white',
    left: 22,
    top: 8,
    zIndex: 999,
    paddingHorizontal: 2,
    fontSize: 14,
  },
  placeholderStyle: {
    fontSize: 16,
  },
  selectedTextStyle: {
    fontSize: 16,
  },
  iconStyle: {
    width: 20,
    height: 20,
  },
  inputSearchStyle: {
    height: 30,
    fontSize: 16,
  },
});

I'm using it like this -

          <InputWithIcon
            field={detail}
            icon={options[detail].icon}
            values={options[detail].values}
          />

I'm getting this warning in console -

console.js:288 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.
Screenshot 2024-09-25 at 11 39 27 AM

console.log('Value or Focus changed: ', { value, isFocus }); only prints when Dropdown is interacted with.
I have tried debugging it and managed to pinpoint it to using Dropdown component. Kindly assist.

@hoaphantn7604 can you have a look ?

I had the same issue, and for some reason it happens when you have an empty array.
I made a small patch in the module on line 150. Try adding it and patch-package the module.
*** JUST A HOTFIX FOR ME ***

    useEffect(() => {
      if (data && data.length > 0) {
        const filterData = excludeData(data);
        setListData([...filterData]);
        if (searchText) {
          onSearch(searchText);
        }
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [data, searchText]);

I had the same issue, and for some reason it happens when you have an empty array. I made a small patch in the module on line 150. Try adding it and patch-package the module. *** JUST A HOTFIX FOR ME ***

    useEffect(() => {
      if (data && data.length > 0) {
        const filterData = excludeData(data);
        setListData([...filterData]);
        if (searchText) {
          onSearch(searchText);
        }
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [data, searchText]);

#304

I also made a hotfix for it